diff --git a/analyzers/archive-analyzer.html b/analyzers/archive-analyzer.html index e4e382572..aab7add4a 100644 --- a/analyzers/archive-analyzer.html +++ b/analyzers/archive-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Archive Analyzer @@ -59,9 +59,9 @@
  • Archive Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees diff --git a/analyzers/assembly-analyzer.html b/analyzers/assembly-analyzer.html index 7c932bc4e..71843a75e 100644 --- a/analyzers/assembly-analyzer.html +++ b/analyzers/assembly-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Assembly Analyzer @@ -59,9 +59,9 @@
  • Assembly Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees diff --git a/analyzers/autoconf.html b/analyzers/autoconf.html index 42beebf99..f5071deb2 100644 --- a/analyzers/autoconf.html +++ b/analyzers/autoconf.html @@ -1,13 +1,13 @@ - + dependency-check – Autoconf Analyzer @@ -59,9 +59,9 @@
  • Autoconf Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees @@ -236,6 +233,7 @@

    Autoconf Analyzer

    +

    Experimental: This analyzer is considered experimental. While this analyzer may be useful and provide valid results more testing must be completed to ensure that the false negative/false positive rates are acceptable.

    OWASP dependency-check includes an analyzer that will scan Autoconf project configuration files. The analyzer will collect as much information it can about the project. The information collected is internally referred to as evidence and is grouped into vendor, product, and version buckets. Other analyzers later use this evidence to identify any Common Platform Enumeration (CPE) identifiers that apply.

    File names scanned: configure, configure.in, configure.ac

    diff --git a/analyzers/central-analyzer.html b/analyzers/central-analyzer.html index d23e68a95..722eaab9b 100644 --- a/analyzers/central-analyzer.html +++ b/analyzers/central-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Central Analyzer @@ -59,9 +59,9 @@
  • Central Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees diff --git a/analyzers/cmake.html b/analyzers/cmake.html index 483fa395f..a62fcacd4 100644 --- a/analyzers/cmake.html +++ b/analyzers/cmake.html @@ -1,13 +1,13 @@ - + dependency-check – CMake Analyzer @@ -59,9 +59,9 @@
  • CMake Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees @@ -236,6 +233,7 @@

    CMake Analyzer

    +

    Experimental: This analyzer is considered experimental. While this analyzer may be useful and provide valid results more testing must be completed to ensure that the false negative/false positive rates are acceptable.

    OWASP dependency-check includes an analyzer that will scan CMake project configuration files. The analyzer will collect as much information it can about the project. The information collected is internally referred to as evidence and is grouped into vendor, product, and version buckets. Other analyzers later use this evidence to identify any Common Platform Enumeration (CPE) identifiers that apply.

    File names scanned: CMakeLists.txt, *.cmake

    diff --git a/analyzers/composer-lock.html b/analyzers/composer-lock.html index 68f0a8eff..38b18d90e 100644 --- a/analyzers/composer-lock.html +++ b/analyzers/composer-lock.html @@ -1,13 +1,13 @@ - + dependency-check – Composer Lock Analyzer @@ -59,9 +59,9 @@
  • Composer Lock Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -140,9 +140,6 @@ developed using - - - built on cloudbees @@ -152,6 +149,7 @@

    Composer Lock Analyzer

    +

    Experimental: This analyzer is considered experimental. While this analyzer may be useful and provide valid results more testing must be completed to ensure that the false negative/false positive rates are acceptable.

    OWASP dependency-check includes an analyzer that scans composer.lock files to get exact dependency version information from PHP projects which are managed with Composer. If you’re using Composer to manage your project, this will only analyze the composer.lock file currently, so you’ll need to run composer install to have Composer generate this file.

    diff --git a/analyzers/index.html b/analyzers/index.html index 34a7c0ff5..62722b1bf 100644 --- a/analyzers/index.html +++ b/analyzers/index.html @@ -1,13 +1,13 @@ - + dependency-check – File Type Analyzers @@ -59,9 +59,9 @@
  • File Type Analyzers
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees @@ -272,24 +269,6 @@ -Autoconf - -Autoconf project configuration files (configure, configure.in, configure.ac) - -Regex scan for AC_INIT metadata, including in generated configuration script. - - - - -Central - -Java archive files (*.jar) - -Searches Maven Central or a configured Nexus repository for the file’s SHA1 hash. - - - - CMake CMake project files (CMakeLists.txt) and scripts (*.cmake) @@ -299,15 +278,6 @@ -Composer Lock - -PHP Composer Lock files (composer.lock) - -Parses PHP Composer lock files for exact versions of dependencies. - - - - Jar Java archive files (*.jar); Web application archive (*.war) @@ -315,26 +285,8 @@ Examines archive manifest metadata, and Maven Project Object Model files (pom.xml). - - -Nexus - -Java archive files (*.jar) - -Searches Sonatype or a configured Nexus repository for the file’s SHA1 hash. In most cases, superceded by Central . - - -Node.js - -NPM package specification files (package.json) - -Parse JSON format for metadata. - - - - Nuspec Nuget package specification file (*.nuspec) @@ -342,7 +294,7 @@ Uses XPath to parse specification XML. - + OpenSSL @@ -350,9 +302,64 @@ Regex parse of the OPENSSL_VERSION_NUMBER macro definition. + + +
    +

    Experimental Analyzers

    +

    The following analyzers can be enabled by enabling the experimental configuration option; see the documentation for the CLI, Ant, Maven, etc. for more information. These analyzers are considered experimental due to the higher false positive and false negative rates. Even though these are marked as experimental several teams have found them useful in their current state.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -360,7 +367,7 @@ - + @@ -369,7 +376,7 @@ -
    Analyzer File Types Scanned Analysis Method
    Autoconf Autoconf project configuration files (configure, configure.in, configure.ac) Regex scan for AC_INIT metadata, including in generated configuration script.
    CMake CMake project files (CMakeLists.txt) and scripts (*.cmake) Regex scan for project initialization and version setting commands.
    Composer Lock PHP Composer Lock files (composer.lock) Parses PHP Composer lock files for exact versions of dependencies.
    Node.js NPM package specification files (package.json) Parse JSON format for metadata.
    Python Python source files (*.py); Package metadata files (PKG-INFO, METADATA); Package Distribution Files (*.whl, *.egg, *.zip) Regex scan of Python source files for setuptools metadata; Parse RFC822 header format for metadata in all other artifacts.
    Ruby Gemspec Regex scan Gemspec initialization blocks for metadata.
    +
    diff --git a/analyzers/jar-analyzer.html b/analyzers/jar-analyzer.html index 0856efeee..e7d032d9a 100644 --- a/analyzers/jar-analyzer.html +++ b/analyzers/jar-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Jar Analyzer @@ -59,9 +59,9 @@
  • Jar Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees diff --git a/analyzers/nexus-analyzer.html b/analyzers/nexus-analyzer.html index 03be2f67a..32c9d4f3a 100644 --- a/analyzers/nexus-analyzer.html +++ b/analyzers/nexus-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Nexus Analyzer @@ -59,9 +59,9 @@
  • Nexus Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees diff --git a/analyzers/nodejs.html b/analyzers/nodejs.html index e8edb969f..690dc0302 100644 --- a/analyzers/nodejs.html +++ b/analyzers/nodejs.html @@ -1,13 +1,13 @@ - + dependency-check – Node.js Analyzer @@ -59,9 +59,9 @@
  • Node.js Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees @@ -236,8 +233,9 @@

    Node.js Analyzer

    +

    Experimental: This analyzer is considered experimental. While this analyzer may be useful and provide valid results more testing must be completed to ensure that the false negative/false positive rates are acceptable.

    OWASP dependency-check includes an analyzer that will scan Node Package Manager package specification files. The analyzer will collect as much information as it can about the package. The information collected is internally referred to as evidence and is grouped into vendor, product, and version buckets. Other analyzers later use this evidence to identify any Common Platform Enumeration (CPE) identifiers that apply.

    -

    Note:_Consider using Retire.js or the Node Security Project auditing tool, nsp instead of, or in addition to OWASP dependency-check to analyze Node.js packages.

    +

    Note: Consider using Retire.js or the Node Security Project auditing tool, nsp instead of, or in addition to OWASP dependency-check to analyze Node.js packages.

    Files Types Scanned: package.json

    diff --git a/analyzers/nuspec-analyzer.html b/analyzers/nuspec-analyzer.html index 40eaa89cd..4b0a40e24 100644 --- a/analyzers/nuspec-analyzer.html +++ b/analyzers/nuspec-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Nuspec Analyzer @@ -59,9 +59,9 @@
  • Nuspec Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees diff --git a/analyzers/openssl.html b/analyzers/openssl.html index c8ed29d4f..11c188d3e 100644 --- a/analyzers/openssl.html +++ b/analyzers/openssl.html @@ -1,13 +1,13 @@ - + dependency-check – OpenSSL Analyzer @@ -59,9 +59,9 @@
  • OpenSSL Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees diff --git a/analyzers/python.html b/analyzers/python.html index 404df18df..e8dee681f 100644 --- a/analyzers/python.html +++ b/analyzers/python.html @@ -1,13 +1,13 @@ - + dependency-check – Python Analyzer @@ -59,9 +59,9 @@
  • Python Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees @@ -236,6 +233,7 @@

    Python Analyzer

    +

    Experimental: This analyzer is considered experimental. While this analyzer may be useful and provide valid results more testing must be completed to ensure that the false negative/false positive rates are acceptable.

    OWASP dependency-check includes an analyzer that will scan Python artifacts. The analyzer(s) will collect as much information it can about the Python artifacts. The information collected is internally referred to as evidence and is grouped into vendor, product, and version buckets. Other analyzers later use this evidence to identify any Common Platform Enumeration (CPE) identifiers that apply.

    Files Types Scanned: py, whl, egg, zip, PKG-INFO, and METADATA

    diff --git a/analyzers/ruby-gemspec.html b/analyzers/ruby-gemspec.html index 0987bc144..6cf6d439e 100644 --- a/analyzers/ruby-gemspec.html +++ b/analyzers/ruby-gemspec.html @@ -1,13 +1,13 @@ - + dependency-check – Ruby Gemspec Analyzer @@ -59,9 +59,9 @@
  • Ruby Gemspec Analyzer
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -224,9 +224,6 @@ developed using - - - built on cloudbees @@ -236,8 +233,9 @@

    Ruby Gemspec Analyzer

    +

    Experimental: This analyzer is considered experimental. While this analyzer may be useful and provide valid results more testing must be completed to ensure that the false negative/false positive rates are acceptable.

    OWASP dependency-check includes an analyzer that will scan Ruby Gem specifications. The analyzer will collect as much information as it can about the Gem. The information collected is internally referred to as evidence and is grouped into vendor, product, and version buckets. Other analyzers later use this evidence to identify any Common Platform Enumeration (CPE) identifiers that apply.

    -

    Note: It is highly recommended that Ruby projects use bundler-audit.

    +

    Note: It is highly recommended that Ruby projects use bundler-audit.

    Files Types Scanned: Rakefile, *.gemspec

    diff --git a/current.txt b/current.txt index 6f96ed081..e21e727f9 100644 --- a/current.txt +++ b/current.txt @@ -1 +1 @@ -1.3.6 \ No newline at end of file +1.4.0 \ No newline at end of file diff --git a/data/cachenvd.html b/data/cachenvd.html index 748f2218d..d743827cc 100644 --- a/data/cachenvd.html +++ b/data/cachenvd.html @@ -1,13 +1,13 @@ - + dependency-check – Snapshotting the NVD @@ -59,9 +59,9 @@
  • Snapshotting the NVD
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -233,9 +233,6 @@ developed using - - - built on cloudbees diff --git a/data/database.html b/data/database.html index 79da60df3..000b742fa 100644 --- a/data/database.html +++ b/data/database.html @@ -1,13 +1,13 @@ - + dependency-check – Using a Database Server @@ -59,9 +59,9 @@
  • Using a Database Server
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -233,9 +233,6 @@ developed using - - - built on cloudbees diff --git a/data/index.html b/data/index.html index a57833e7e..157484ce9 100644 --- a/data/index.html +++ b/data/index.html @@ -1,13 +1,13 @@ - + dependency-check – Internet Access Required @@ -59,9 +59,9 @@
  • Internet Access Required
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -233,9 +233,6 @@ developed using - - - built on cloudbees @@ -261,7 +258,7 @@

    Downloading Additional Information

    -

    If the machine that is running dependency-check cannot reach the Central Repository the analysis may result in false negatives. This is because some POM files, that are not contained within the JAR file itself, contain evidence that is used to accurately identify a library. If Central cannot be reached, it is highly recommended to setup a Nexus server within your organization and to configure dependency-check to use the local Nexus server. Note, even with a Nexus server setup I have seen dependency-check be re-directed to other repositories on the Internet to download the actual POM file.

    +

    If the machine that is running dependency-check cannot reach the Central Repository the analysis may result in false negatives. This is because some POM files, that are not contained within the JAR file itself, contain evidence that is used to accurately identify a library. If Central cannot be reached, it is highly recommended to setup a Nexus server within your organization and to configure dependency-check to use the local Nexus server. Note, even with a Nexus server setup I have seen dependency-check be re-directed to other repositories on the Internet to download the actual POM file; this happened due to a rare circumstance where the Nexus instance used by dependency-check was not the instance of Nexus used to build the application (i.e. the dependencies were not actually present in the Nexus used by dependency-check).

    diff --git a/data/mirrornvd.html b/data/mirrornvd.html index c596de8ed..bbe3f485e 100644 --- a/data/mirrornvd.html +++ b/data/mirrornvd.html @@ -1,13 +1,13 @@ - + dependency-check – Mirroring the NVD from NIST @@ -59,9 +59,9 @@
  • Mirroring the NVD from NIST
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -233,9 +233,6 @@ developed using - - - built on cloudbees diff --git a/data/proxy.html b/data/proxy.html index c56d41c50..88659f7c3 100644 --- a/data/proxy.html +++ b/data/proxy.html @@ -1,13 +1,13 @@ - + dependency-check – Proxy Configuration @@ -59,9 +59,9 @@
  • Proxy Configuration
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -233,9 +233,6 @@ developed using - - - built on cloudbees @@ -256,6 +253,13 @@
  • Maven Plugin
  • Note, it may also be possible to use the core Java proxy system properties instead of the configuration above.

    +
    +

    Certificate Errors

    +

    In some cases if you setup a proxy the connection may still fail due to certificate errors (see the log file from dependency-check). If you know which cert it’s failing on (either your proxy or NVD/CVE) you can either add the certificate itself or the signing chain to your trust store. If you don’t have access to modify the system trust store (in $JAVA_HOME/lib/security/cacerts) you can copy it elsewhere and import it using keytool, then specify that trust store on the command line (mvn -Djavax.net.ssl.trustStore=/path/to/cacerts) or if you need to always have that set, you can set the environment variable JAVA_TOOL_OPTIONS to have -Djavax.net.ssl.trustStore=/path/to/cacerts.

    +
    +

    Still failing?

    +

    In some cases the proxy is configured to block HEAD requests. While an attempt is made by dependency-check to identify this situation it does not appear to be 100% successful. As such, the last thing to try is to add the property mvn -Ddownloader.quick.query.timestamp=false.

    +

    If trying the above and it still fails please open a ticket in the github repo.

    diff --git a/data/upgrade.html b/data/upgrade.html index c8c2b03ce..57ae6b181 100644 --- a/data/upgrade.html +++ b/data/upgrade.html @@ -1,13 +1,13 @@ - + dependency-check – Database Upgrades @@ -59,9 +59,9 @@
  • Database Upgrades
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -140,9 +140,6 @@ developed using - - - built on cloudbees diff --git a/dependency-analysis.html b/dependency-analysis.html index 5583fe7a6..579c2a355 100644 --- a/dependency-analysis.html +++ b/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check – @@ -59,9 +59,9 @@
  • -
  • | Last Published: 2016-04-09
  • +
  • | Last Published: 2016-06-16
  • - Version: 1.3.6 + Version: 1.4.0
  • @@ -182,9 +182,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/apidocs/allclasses-frame.html b/dependency-check-ant/apidocs/allclasses-frame.html index 99504f9aa..2d007a06e 100644 --- a/dependency-check-ant/apidocs/allclasses-frame.html +++ b/dependency-check-ant/apidocs/allclasses-frame.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Ant Task 1.3.6 API) - +All Classes (Dependency-Check Ant Task 1.4.0 API) + diff --git a/dependency-check-ant/apidocs/allclasses-noframe.html b/dependency-check-ant/apidocs/allclasses-noframe.html index 357f618dc..3c32881a4 100644 --- a/dependency-check-ant/apidocs/allclasses-noframe.html +++ b/dependency-check-ant/apidocs/allclasses-noframe.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Ant Task 1.3.6 API) - +All Classes (Dependency-Check Ant Task 1.4.0 API) + diff --git a/dependency-check-ant/apidocs/constant-values.html b/dependency-check-ant/apidocs/constant-values.html index 15587ed4a..81be668ff 100644 --- a/dependency-check-ant/apidocs/constant-values.html +++ b/dependency-check-ant/apidocs/constant-values.html @@ -2,10 +2,10 @@ - + -Constant Field Values (Dependency-Check Ant Task 1.3.6 API) - +Constant Field Values (Dependency-Check Ant Task 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-summary.html b/dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-summary.html index 25265e3a0..4122dca57 100644 --- a/dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-summary.html +++ b/dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.ant.logging (Dependency-Check Ant Task 1.3.6 API) - +org.owasp.dependencycheck.ant.logging (Dependency-Check Ant Task 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,13 +13,13 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-ant/apidocs/org/owasp/dependencycheck/taskdefs/package-summary.html b/dependency-check-ant/apidocs/org/owasp/dependencycheck/taskdefs/package-summary.html index a32293378..32626b84c 100644 --- a/dependency-check-ant/apidocs/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/dependency-check-ant/apidocs/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.taskdefs (Dependency-Check Ant Task 1.3.6 API) - +org.owasp.dependencycheck.taskdefs (Dependency-Check Ant Task 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-ant/apidocs/org/slf4j/impl/package-summary.html b/dependency-check-ant/apidocs/org/slf4j/impl/package-summary.html index b12aa57a4..2bc885b85 100644 --- a/dependency-check-ant/apidocs/org/slf4j/impl/package-summary.html +++ b/dependency-check-ant/apidocs/org/slf4j/impl/package-summary.html @@ -2,10 +2,10 @@ - + -org.slf4j.impl (Dependency-Check Ant Task 1.3.6 API) - +org.slf4j.impl (Dependency-Check Ant Task 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-ant/apidocs/overview-summary.html b/dependency-check-ant/apidocs/overview-summary.html index 4b48d1be7..d19102b0c 100644 --- a/dependency-check-ant/apidocs/overview-summary.html +++ b/dependency-check-ant/apidocs/overview-summary.html @@ -2,10 +2,10 @@ - + -Overview (Dependency-Check Ant Task 1.3.6 API) - +Overview (Dependency-Check Ant Task 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ - + diff --git a/dependency-check-ant/cobertura/frame-summary-org.owasp.dependencycheck.taskdefs.html b/dependency-check-ant/cobertura/frame-summary-org.owasp.dependencycheck.taskdefs.html index 7176677af..7c4a174af 100644 --- a/dependency-check-ant/cobertura/frame-summary-org.owasp.dependencycheck.taskdefs.html +++ b/dependency-check-ant/cobertura/frame-summary-org.owasp.dependencycheck.taskdefs.html @@ -16,7 +16,7 @@ - +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.taskdefs4
    47%
    167/351
    51%
    41/80
    1.548
    org.owasp.dependencycheck.taskdefs4
    47%
    168/355
    50%
    40/80
    1.538
    - + diff --git a/dependency-check-ant/cobertura/frame-summary-org.slf4j.impl.html b/dependency-check-ant/cobertura/frame-summary-org.slf4j.impl.html index fa1c11415..842d8e428 100644 --- a/dependency-check-ant/cobertura/frame-summary-org.slf4j.impl.html +++ b/dependency-check-ant/cobertura/frame-summary-org.slf4j.impl.html @@ -37,6 +37,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-ant/cobertura/frame-summary.html b/dependency-check-ant/cobertura/frame-summary.html index 107b27518..7e2658471 100644 --- a/dependency-check-ant/cobertura/frame-summary.html +++ b/dependency-check-ant/cobertura/frame-summary.html @@ -16,9 +16,9 @@ - + - +
    Package # Classes Line Coverage Branch Coverage Complexity
    All Packages7
    46%
    217/468
    41%
    54/130
    1.573
    All Packages7
    46%
    218/472
    40%
    53/130
    1.566
    org.owasp.dependencycheck.ant.logging2
    35%
    37/104
    26%
    13/50
    1.735
    org.owasp.dependencycheck.taskdefs4
    47%
    167/351
    51%
    41/80
    1.548
    org.owasp.dependencycheck.taskdefs4
    47%
    168/355
    50%
    40/80
    1.538
    org.slf4j.impl1
    100%
    13/13
    N/A
    1
    @@ -27,6 +27,6 @@ var packageTable = new SortableTable(document.getElementById("packageResults"), ["String", "Number", "Percentage", "Percentage", "FormattedNumber"]); packageTable.sort(0); - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerAdapter.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerAdapter.html index 2aab2fefb..6cb7a0145 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerAdapter.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerAdapter.html @@ -103,9 +103,9 @@
          */
     43  
         public AntLoggerAdapter(Task task) {
    -  44  13
             super();
    -  45  13
             this.task = task;
    -  46  13
         }
    +  44  26
             super();
    +  45  26
             this.task = task;
    +  46  26
         }
     47  
     
     48   @@ -141,23 +141,23 @@
         @Override
     65  
         public void trace(String msg) {
    -  66  29
             if (task != null) {
    -  67  27
                 task.log(msg, Project.MSG_VERBOSE);
    +  66  61
             if (task != null) {
    +  67  54
                 task.log(msg, Project.MSG_VERBOSE);
     68  
             }
    -  69  29
         }
    +  69  61
         }
     70  
     
     71  
         @Override
     72  
         public void trace(String format, Object arg) {
    -  73  29
             if (task != null) {
    -  74  21
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    -  75  21
                 task.log(tp.getMessage(), Project.MSG_VERBOSE);
    +  73  58
             if (task != null) {
    +  74  42
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    +  75  42
                 task.log(tp.getMessage(), Project.MSG_VERBOSE);
     76  
             }
    -  77  29
         }
    +  77  58
         }
     78  
     
     79   @@ -199,7 +199,7 @@
         @Override
     103  
         public boolean isDebugEnabled() {
    -  104  10
             return true;
    +  104  20
             return true;
     105  
         }
     106   @@ -208,47 +208,47 @@
         @Override
     108  
         public void debug(String msg) {
    -  109  133
             if (task != null) {
    -  110  119
                 task.log(msg, Project.MSG_DEBUG);
    +  109  268
             if (task != null) {
    +  110  234
                 task.log(msg, Project.MSG_DEBUG);
     111  
             }
    -  112  133
         }
    +  112  268
         }
     113  
     
     114  
         @Override
     115  
         public void debug(String format, Object arg) {
    -  116  370
             if (task != null) {
    -  117  357
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    -  118  357
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
    +  116  660
             if (task != null) {
    +  117  634
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    +  118  634
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
     119  
             }
    -  120  370
         }
    +  120  660
         }
     121  
     
     122  
         @Override
     123  
         public void debug(String format, Object arg1, Object arg2) {
    -  124  21
             if (task != null) {
    -  125  15
                 final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
    -  126  15
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
    +  124  50
             if (task != null) {
    +  125  38
                 final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
    +  126  38
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
     127  
             }
    -  128  21
         }
    +  128  50
         }
     129  
     
     130  
         @Override
     131  
         public void debug(String format, Object... arguments) {
    -  132  2
             if (task != null) {
    -  133  2
                 final FormattingTuple tp = MessageFormatter.format(format, arguments);
    -  134  2
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
    +  132  4
             if (task != null) {
    +  133  4
                 final FormattingTuple tp = MessageFormatter.format(format, arguments);
    +  134  4
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
     135  
             }
    -  136  2
         }
    +  136  4
         }
     137  
     
     138   @@ -275,23 +275,23 @@
         @Override
     151  
         public void info(String msg) {
    -  152  6
             if (task != null) {
    -  153  6
                 task.log(msg, Project.MSG_INFO);
    +  152  12
             if (task != null) {
    +  153  12
                 task.log(msg, Project.MSG_INFO);
     154  
             }
    -  155  6
         }
    +  155  12
         }
     156  
     
     157  
         @Override
     158  
         public void info(String format, Object arg) {
    -  159  6
             if (task != null) {
    -  160  6
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    -  161  6
                 task.log(tp.getMessage(), Project.MSG_INFO);
    +  159  12
             if (task != null) {
    +  160  12
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    +  161  12
                 task.log(tp.getMessage(), Project.MSG_INFO);
     162  
             }
    -  163  6
         }
    +  163  12
         }
     164  
     
     165   @@ -465,6 +465,6 @@
     }
    - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerFactory.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerFactory.html index 06199530c..982f58e7a 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerFactory.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerFactory.html @@ -99,9 +99,9 @@
          */
     41  
         public AntLoggerFactory(Task task) {
    -  42  13
             super();
    -  43  13
             this.antLoggerAdapter = new AntLoggerAdapter(task);
    -  44  13
         }
    +  42  26
             super();
    +  43  26
             this.antLoggerAdapter = new AntLoggerAdapter(task);
    +  44  26
         }
     45  
     
     46   @@ -120,13 +120,13 @@
         @Override
     53  
         public Logger getLogger(String name) {
    -  54  44
             return antLoggerAdapter;
    +  54  92
             return antLoggerAdapter;
     55  
         }
     56  
     }
    - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Check.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Check.html index e0727cc24..61ab76bc2 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Check.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Check.html @@ -12,8 +12,8 @@
     
    - - + +
    Classes in this File Line Coverage Branch Coverage Complexity
    Check
    53%
    122/228
    56%
    36/64
    1.667
    Check$ReportFormats
    100%
    7/7
    100%
    2/2
    1.667
    Check
    53%
    123/232
    54%
    35/64
    1.647
    Check$ReportFormats
    100%
    7/7
    100%
    2/2
    1.647
     
    @@ -122,7 +122,7 @@
          * System specific new line character.
     52  
          */
    -  53  1
         private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
    +  53  2
         private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
     54  
     
     55   @@ -133,13 +133,13 @@
          */
     58  
         public Check() {
    -  59  4
             super();
    +  59  8
             super();
     60  
             // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
     61  
             // core end up coming through this tasks logger
    -  62  4
             StaticLoggerBinder.getSingleton().setTask(this);
    -  63  4
         }
    +  62  8
             StaticLoggerBinder.getSingleton().setTask(this);
    +  63  8
         }
     64  
         //The following code was copied Apache Ant PathConvert
     65   @@ -150,14 +150,14 @@
          * Path to be converted
     68  
          */
    -  69  4
         private Resources path = null;
    +  69  8
         private Resources path = null;
     70  
         /**
     71  
          * Reference to path/fileset to convert
     72  
          */
    -  73  4
         private Reference refid = null;
    +  73  8
         private Reference refid = null;
     74  
     
     75   @@ -174,20 +174,20 @@
          */
     81  
         public void add(ResourceCollection rc) {
    -  82  4
             if (isReference()) {
    +  82  8
             if (isReference()) {
     83  0
                 throw new BuildException("Nested elements are not allowed when using the refid attribute.");
     84  
             }
    -  85  4
             getPath().add(rc);
    -  86  4
         }
    +  85  8
             getPath().add(rc);
    +  86  8
         }
     87  
     
     88  
         /**
     89   -
          * Returns the path. If the path has not been initialized yet, this class is synchronized, and will instantiate the path
    +
          * Returns the path. If the path has not been initialized yet, this class is
     90   -
          * object.
    +
          * synchronized, and will instantiate the path object.
     91  
          *
     92   @@ -196,12 +196,12 @@
          */
     94  
         private synchronized Resources getPath() {
    -  95  4
             if (path == null) {
    -  96  3
                 path = new Resources(getProject());
    -  97  3
                 path.setCache(true);
    +  95  8
             if (path == null) {
    +  96  6
                 path = new Resources(getProject());
    +  97  6
                 path.setCache(true);
     98  
             }
    -  99  4
             return path;
    +  99  8
             return path;
     100  
         }
     101   @@ -218,7 +218,7 @@
          */
     107  
         public boolean isReference() {
    -  108  8
             return refid != null;
    +  108  16
             return refid != null;
     109  
         }
     110   @@ -226,1497 +226,1567 @@  111  
         /**
     112   -
          * Add a reference to a Path, FileSet, DirSet, or FileList defined elsewhere.
    +
          * Add a reference to a Path, FileSet, DirSet, or FileList defined
     113   -
          *
    +
          * elsewhere.
     114   -
          * @param r the reference to a path, fileset, dirset or filelist.
    +
          *
     115   -
          */
    +
          * @param r the reference to a path, fileset, dirset or filelist.
     116   +
          */
    +  117  
         public void setRefid(Reference r) {
    -  117  0
             if (path != null) {
    -  118  0
                 throw new BuildException("Nested elements are not allowed when using the refid attribute.");
    -  119   +  118  0
             if (path != null) {
    +  119  0
                 throw new BuildException("Nested elements are not allowed when using the refid attribute.");
    +  120  
             }
    -  120  0
             refid = r;
    -  121  0
         }
    -  122   -
     
    +  121  0
             refid = r;
    +  122  0
         }
     123   -
         /**
    -  124   -
          * If this is a reference, this method will add the referenced resource collection to the collection of paths.
    -  125   -
          *
    -  126   -
          * @throws BuildException if the reference is not to a resource collection
    -  127   -
          */
    -  128   -
         private void dealWithReferences() throws BuildException {
    -  129  4
             if (isReference()) {
    -  130  0
                 final Object o = refid.getReferencedObject(getProject());
    -  131  0
                 if (!(o instanceof ResourceCollection)) {
    -  132  0
                     throw new BuildException("refid '" + refid.getRefId()
    -  133   -
                             + "' does not refer to a resource collection.");
    -  134   -
                 }
    -  135  0
                 getPath().add((ResourceCollection) o);
    -  136   -
             }
    -  137  4
         }
    -  138   -
         // END COPY from org.apache.tools.ant.taskdefs
    -  139   -
         /**
    -  140   -
          * The application name for the report.
    -  141   -
          *
    -  142   -
          * @deprecated use projectName instead.
    -  143   -
          */
    -  144  4
         @Deprecated
    -  145   -
         private String applicationName = null;
    -  146  
     
    -  147   +  124  
         /**
    -  148   -
          * Get the value of applicationName.
    -  149   +  125   +
          * If this is a reference, this method will add the referenced resource
    +  126   +
          * collection to the collection of paths.
    +  127  
          *
    +  128   +
          * @throws BuildException if the reference is not to a resource collection
    +  129   +
          */
    +  130   +
         private void dealWithReferences() throws BuildException {
    +  131  8
             if (isReference()) {
    +  132  0
                 final Object o = refid.getReferencedObject(getProject());
    +  133  0
                 if (!(o instanceof ResourceCollection)) {
    +  134  0
                     throw new BuildException("refid '" + refid.getRefId()
    +  135   +
                             + "' does not refer to a resource collection.");
    +  136   +
                 }
    +  137  0
                 getPath().add((ResourceCollection) o);
    +  138   +
             }
    +  139  8
         }
    +  140   +
         // END COPY from org.apache.tools.ant.taskdefs
    +  141   +
         /**
    +  142   +
          * The application name for the report.
    +  143   +
          *
    +  144   +
          * @deprecated use projectName instead.
    +  145   +
          */
    +  146  8
         @Deprecated
    +  147   +
         private String applicationName = null;
    +  148   +
     
    +  149   +
         /**
     150   -
          * @return the value of applicationName
    +
          * Get the value of applicationName.
     151  
          *
     152   -
          * @deprecated use projectName instead.
    +
          * @return the value of applicationName
     153   -
          */
    +
          *
     154   -
         @Deprecated
    -  155   -
         public String getApplicationName() {
    -  156  0
             return applicationName;
    -  157   -
         }
    -  158   -
     
    -  159   -
         /**
    -  160   -
          * Set the value of applicationName.
    -  161   -
          *
    -  162   -
          * @param applicationName new value of applicationName
    -  163  
          * @deprecated use projectName instead.
    +  155   +
          */
    +  156   +
         @Deprecated
    +  157   +
         public String getApplicationName() {
    +  158  0
             return applicationName;
    +  159   +
         }
    +  160   +
     
    +  161   +
         /**
    +  162   +
          * Set the value of applicationName.
    +  163   +
          *
     164   -
          */
    +
          * @param applicationName new value of applicationName
     165   -
         @Deprecated
    +
          * @deprecated use projectName instead.
     166   +
          */
    +  167   +
         @Deprecated
    +  168  
         public void setApplicationName(String applicationName) {
    -  167  4
             this.applicationName = applicationName;
    -  168  4
         }
    -  169   -
         /**
    -  170   -
          * The name of the project being analyzed.
    +  169  8
             this.applicationName = applicationName;
    +  170  8
         }
     171   -
          */
    -  172  4
         private String projectName = "dependency-check";
    +
         /**
    +  172   +
          * The name of the project being analyzed.
     173   -
     
    -  174   -
         /**
    +
          */
    +  174  8
         private String projectName = "dependency-check";
     175   -
          * Get the value of projectName.
    +
     
     176   -
          *
    +
         /**
     177   -
          * @return the value of projectName
    +
          * Get the value of projectName.
     178   -
          */
    +
          *
     179   +
          * @return the value of projectName
    +  180   +
          */
    +  181  
         public String getProjectName() {
    -  180  3
             if (applicationName != null) {
    -  181  3
                 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN);
    -  182  3
                 if ("dependency-check".equals(projectName)) {
    -  183  3
                     projectName = applicationName;
    -  184   +  182  6
             if (applicationName != null) {
    +  183  6
                 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN);
    +  184  6
                 if ("dependency-check".equals(projectName)) {
    +  185  6
                     projectName = applicationName;
    +  186  
                 }
    -  185   -
             }
    -  186  3
             return projectName;
     187   -
         }
    -  188   -
     
    +
             }
    +  188  6
             return projectName;
     189   -
         /**
    +
         }
     190   -
          * Set the value of projectName.
    +
     
     191   -
          *
    +
         /**
     192   -
          * @param projectName new value of projectName
    +
          * Set the value of projectName.
     193   -
          */
    +
          *
     194   +
          * @param projectName new value of projectName
    +  195   +
          */
    +  196  
         public void setProjectName(String projectName) {
    -  195  0
             this.projectName = projectName;
    -  196  0
         }
    -  197   -
     
    -  198   -
         /**
    +  197  0
             this.projectName = projectName;
    +  198  0
         }
     199   -
          * Specifies the destination directory for the generated Dependency-Check report.
    +
     
     200   -
          */
    -  201  4
         private String reportOutputDirectory = ".";
    +
         /**
    +  201   +
          * Specifies the destination directory for the generated Dependency-Check
     202   -
     
    +
          * report.
     203   -
         /**
    -  204   -
          * Get the value of reportOutputDirectory.
    +
          */
    +  204  8
         private String reportOutputDirectory = ".";
     205   -
          *
    +
     
     206   -
          * @return the value of reportOutputDirectory
    +
         /**
     207   -
          */
    +
          * Get the value of reportOutputDirectory.
     208   -
         public String getReportOutputDirectory() {
    -  209  0
             return reportOutputDirectory;
    +
          *
    +  209   +
          * @return the value of reportOutputDirectory
     210   -
         }
    +
          */
     211   -
     
    -  212   -
         /**
    +
         public String getReportOutputDirectory() {
    +  212  0
             return reportOutputDirectory;
     213   -
          * Set the value of reportOutputDirectory.
    +
         }
     214   -
          *
    +
     
     215   -
          * @param reportOutputDirectory new value of reportOutputDirectory
    +
         /**
     216   -
          */
    +
          * Set the value of reportOutputDirectory.
     217   -
         public void setReportOutputDirectory(String reportOutputDirectory) {
    -  218  4
             this.reportOutputDirectory = reportOutputDirectory;
    -  219  4
         }
    +
          *
    +  218   +
          * @param reportOutputDirectory new value of reportOutputDirectory
    +  219   +
          */
     220   -
         /**
    -  221   -
          * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which
    -  222   -
          * means since the CVSS scores are 0-10, by default the build will never fail and the CVSS score is set to 11. The valid range
    +
         public void setReportOutputDirectory(String reportOutputDirectory) {
    +  221  8
             this.reportOutputDirectory = reportOutputDirectory;
    +  222  8
         }
     223   -
          * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail.
    +
         /**
     224   -
          */
    -  225  4
         private float failBuildOnCVSS = 11;
    +
          * Specifies if the build should be failed if a CVSS score above a specified
    +  225   +
          * level is identified. The default is 11 which means since the CVSS scores
     226   -
     
    +
          * are 0-10, by default the build will never fail and the CVSS score is set
     227   -
         /**
    +
          * to 11. The valid range for the fail build on CVSS is 0 to 11, where
     228   -
          * Get the value of failBuildOnCVSS.
    +
          * anything above 10 will not cause the build to fail.
     229   -
          *
    -  230   -
          * @return the value of failBuildOnCVSS
    +
          */
    +  230  8
         private float failBuildOnCVSS = 11;
     231   -
          */
    +
     
     232   -
         public float getFailBuildOnCVSS() {
    -  233  0
             return failBuildOnCVSS;
    +
         /**
    +  233   +
          * Get the value of failBuildOnCVSS.
     234   -
         }
    +
          *
     235   -
     
    +
          * @return the value of failBuildOnCVSS
     236   -
         /**
    +
          */
     237   -
          * Set the value of failBuildOnCVSS.
    -  238   -
          *
    +
         public float getFailBuildOnCVSS() {
    +  238  0
             return failBuildOnCVSS;
     239   -
          * @param failBuildOnCVSS new value of failBuildOnCVSS
    +
         }
     240   -
          */
    +
     
     241   -
         public void setFailBuildOnCVSS(float failBuildOnCVSS) {
    -  242  1
             this.failBuildOnCVSS = failBuildOnCVSS;
    -  243  1
         }
    +
         /**
    +  242   +
          * Set the value of failBuildOnCVSS.
    +  243   +
          *
     244   -
         /**
    +
          * @param failBuildOnCVSS new value of failBuildOnCVSS
     245   -
          * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default
    +
          */
     246   -
          * is true.
    -  247   -
          */
    -  248   -
         private Boolean autoUpdate;
    +
         public void setFailBuildOnCVSS(float failBuildOnCVSS) {
    +  247  2
             this.failBuildOnCVSS = failBuildOnCVSS;
    +  248  2
         }
     249   -
     
    +
         /**
     250   -
         /**
    +
          * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
     251   -
          * Get the value of autoUpdate.
    +
          * recommended that this be turned to false. Default is true.
     252   -
          *
    +
          */
     253   -
          * @return the value of autoUpdate
    +
         private Boolean autoUpdate;
     254   -
          */
    +
     
     255   -
         public Boolean isAutoUpdate() {
    -  256  0
             return autoUpdate;
    +
         /**
    +  256   +
          * Get the value of autoUpdate.
     257   -
         }
    +
          *
     258   -
     
    +
          * @return the value of autoUpdate
     259   -
         /**
    +
          */
     260   -
          * Set the value of autoUpdate.
    -  261   -
          *
    +
         public Boolean isAutoUpdate() {
    +  261  0
             return autoUpdate;
     262   -
          * @param autoUpdate new value of autoUpdate
    -  263   -
          */
    -  264   -
         public void setAutoUpdate(Boolean autoUpdate) {
    -  265  4
             this.autoUpdate = autoUpdate;
    -  266  4
         }
    -  267   -
         /**
    -  268   -
          * Whether only the update phase should be executed.
    -  269   -
          *
    -  270   -
          * @deprecated Use the update task instead
    -  271   -
          */
    -  272  4
         @Deprecated
    -  273   -
         private boolean updateOnly = false;
    -  274   -
     
    -  275   -
         /**
    -  276   -
          * Get the value of updateOnly.
    -  277   -
          *
    -  278   -
          * @return the value of updateOnly
    -  279   -
          * @deprecated Use the update task instead
    -  280   -
          */
    -  281   -
         @Deprecated
    -  282   -
         public boolean isUpdateOnly() {
    -  283  3
             return updateOnly;
    -  284  
         }
    -  285   +  263  
     
    -  286   +  264  
         /**
    -  287   -
          * Set the value of updateOnly.
    -  288   +  265   +
          * Set the value of autoUpdate.
    +  266  
          *
    -  289   -
          * @param updateOnly new value of updateOnly
    -  290   -
          * @deprecated Use the update task instead
    -  291   +  267   +
          * @param autoUpdate new value of autoUpdate
    +  268  
          */
    -  292   -
         @Deprecated
    -  293   -
         public void setUpdateOnly(boolean updateOnly) {
    -  294  0
             this.updateOnly = updateOnly;
    -  295  0
         }
    -  296   -
     
    -  297   +  269   +
         public void setAutoUpdate(Boolean autoUpdate) {
    +  270  8
             this.autoUpdate = autoUpdate;
    +  271  8
         }
    +  272  
         /**
    -  298   -
          * The report format to be generated (HTML, XML, VULN, ALL). Default is HTML.
    -  299   +  273   +
          * Whether only the update phase should be executed.
    +  274   +
          *
    +  275   +
          * @deprecated Use the update task instead
    +  276  
          */
    -  300  4
         private String reportFormat = "HTML";
    +  277  8
         @Deprecated
    +  278   +
         private boolean updateOnly = false;
    +  279   +
     
    +  280   +
         /**
    +  281   +
          * Get the value of updateOnly.
    +  282   +
          *
    +  283   +
          * @return the value of updateOnly
    +  284   +
          * @deprecated Use the update task instead
    +  285   +
          */
    +  286   +
         @Deprecated
    +  287   +
         public boolean isUpdateOnly() {
    +  288  6
             return updateOnly;
    +  289   +
         }
    +  290   +
     
    +  291   +
         /**
    +  292   +
          * Set the value of updateOnly.
    +  293   +
          *
    +  294   +
          * @param updateOnly new value of updateOnly
    +  295   +
          * @deprecated Use the update task instead
    +  296   +
          */
    +  297   +
         @Deprecated
    +  298   +
         public void setUpdateOnly(boolean updateOnly) {
    +  299  0
             this.updateOnly = updateOnly;
    +  300  0
         }
     301  
     
     302  
         /**
     303   -
          * Get the value of reportFormat.
    +
          * The report format to be generated (HTML, XML, VULN, ALL). Default is
     304   -
          *
    +
          * HTML.
     305   -
          * @return the value of reportFormat
    -  306  
          */
    +  306  8
         private String reportFormat = "HTML";
     307   -
         public String getReportFormat() {
    -  308  0
             return reportFormat;
    -  309   -
         }
    -  310  
     
    -  311   +  308  
         /**
    -  312   -
          * Set the value of reportFormat.
    -  313   +  309   +
          * Get the value of reportFormat.
    +  310  
          *
    -  314   -
          * @param reportFormat new value of reportFormat
    -  315   +  311   +
          * @return the value of reportFormat
    +  312  
          */
    +  313   +
         public String getReportFormat() {
    +  314  0
             return reportFormat;
    +  315   +
         }
     316   -
         public void setReportFormat(ReportFormats reportFormat) {
    -  317  4
             this.reportFormat = reportFormat.getValue();
    -  318  4
         }
    -  319   +
     
    +  317  
         /**
    +  318   +
          * Set the value of reportFormat.
    +  319   +
          *
     320   -
          * The path to the suppression file.
    +
          * @param reportFormat new value of reportFormat
     321  
          */
     322   -
         private String suppressionFile;
    -  323   -
     
    -  324   -
         /**
    +
         public void setReportFormat(ReportFormats reportFormat) {
    +  323  8
             this.reportFormat = reportFormat.getValue();
    +  324  8
         }
     325   -
          * Get the value of suppressionFile.
    +
         /**
     326   -
          *
    +
          * The path to the suppression file.
     327   -
          * @return the value of suppressionFile
    +
          */
     328   -
          */
    +
         private String suppressionFile;
     329   -
         public String getSuppressionFile() {
    -  330  0
             return suppressionFile;
    -  331   -
         }
    -  332  
     
    -  333   +  330  
         /**
    -  334   -
          * Set the value of suppressionFile.
    -  335   +  331   +
          * Get the value of suppressionFile.
    +  332  
          *
    -  336   -
          * @param suppressionFile new value of suppressionFile
    -  337   +  333   +
          * @return the value of suppressionFile
    +  334  
          */
    +  335   +
         public String getSuppressionFile() {
    +  336  0
             return suppressionFile;
    +  337   +
         }
     338   -
         public void setSuppressionFile(String suppressionFile) {
    -  339  0
             this.suppressionFile = suppressionFile;
    -  340  0
         }
    -  341   +
     
    +  339  
         /**
    +  340   +
          * Set the value of suppressionFile.
    +  341   +
          *
     342   -
          * flag indicating whether or not to show a summary of findings.
    +
          * @param suppressionFile new value of suppressionFile
     343  
          */
    -  344  4
         private boolean showSummary = true;
    -  345   -
     
    -  346   -
         /**
    +  344   +
         public void setSuppressionFile(String suppressionFile) {
    +  345  0
             this.suppressionFile = suppressionFile;
    +  346  0
         }
     347   -
          * Get the value of showSummary.
    +
         /**
     348   -
          *
    +
          * flag indicating whether or not to show a summary of findings.
     349   -
          * @return the value of showSummary
    -  350  
          */
    +  350  8
         private boolean showSummary = true;
     351   -
         public boolean isShowSummary() {
    -  352  0
             return showSummary;
    +
     
    +  352   +
         /**
     353   -
         }
    +
          * Get the value of showSummary.
     354   -
     
    +
          *
     355   -
         /**
    +
          * @return the value of showSummary
     356   -
          * Set the value of showSummary.
    +
          */
     357   -
          *
    -  358   -
          * @param showSummary new value of showSummary
    +
         public boolean isShowSummary() {
    +  358  0
             return showSummary;
     359   -
          */
    -  360   -
         public void setShowSummary(boolean showSummary) {
    -  361  0
             this.showSummary = showSummary;
    -  362  0
         }
    -  363   -
     
    -  364   -
         /**
    -  365   -
          * Whether or not the Jar Analyzer is enabled.
    -  366   -
          */
    -  367   -
         private Boolean jarAnalyzerEnabled;
    -  368   -
     
    -  369   -
         /**
    -  370   -
          * Returns whether or not the analyzer is enabled.
    -  371   -
          *
    -  372   -
          * @return true if the analyzer is enabled
    -  373   -
          */
    -  374   -
         public Boolean isJarAnalyzerEnabled() {
    -  375  0
             return jarAnalyzerEnabled;
    -  376  
         }
    -  377   +  360  
     
    -  378   +  361  
         /**
    -  379   -
          * Sets whether or not the analyzer is enabled.
    -  380   +  362   +
          * Set the value of showSummary.
    +  363  
          *
    -  381   -
          * @param jarAnalyzerEnabled the value of the new setting
    -  382   +  364   +
          * @param showSummary new value of showSummary
    +  365  
          */
    -  383   -
         public void setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) {
    -  384  0
             this.jarAnalyzerEnabled = jarAnalyzerEnabled;
    -  385  0
         }
    -  386   +  366   +
         public void setShowSummary(boolean showSummary) {
    +  367  0
             this.showSummary = showSummary;
    +  368  0
         }
    +  369   +
     
    +  370  
         /**
    +  371   +
          * Whether experimental analyzers are enabled.
    +  372   +
          */
    +  373   +
         private Boolean enableExperimental;
    +  374   +
     
    +  375   +
         /**
    +  376   +
          * Get the value of enableExperimental.
    +  377   +
          *
    +  378   +
          * @return the value of enableExperimental
    +  379   +
          */
    +  380   +
         public Boolean isEnableExperimental() {
    +  381  0
             return enableExperimental;
    +  382   +
         }
    +  383   +
     
    +  384   +
         /**
    +  385   +
          * Set the value of enableExperimental.
    +  386   +
          *
     387   -
          * Whether or not the Archive Analyzer is enabled.
    +
          * @param enableExperimental new value of enableExperimental
     388  
          */
     389   -
         private Boolean archiveAnalyzerEnabled;
    -  390   -
     
    -  391   -
         /**
    +
         public void setEnableExperimental(Boolean enableExperimental) {
    +  390  0
             this.enableExperimental = enableExperimental;
    +  391  0
         }
     392   -
          * Returns whether or not the analyzer is enabled.
    +
     
     393   -
          *
    +
         /**
     394   -
          * @return true if the analyzer is enabled
    +
          * Whether or not the Jar Analyzer is enabled.
     395  
          */
     396   -
         public Boolean isArchiveAnalyzerEnabled() {
    -  397  0
             return archiveAnalyzerEnabled;
    +
         private Boolean jarAnalyzerEnabled;
    +  397   +
     
     398   -
         }
    +
         /**
     399   -
         /**
    -  400   -
          * Whether or not the .NET Assembly Analyzer is enabled.
    -  401   -
          */
    -  402   -
         private Boolean assemblyAnalyzerEnabled;
    -  403   -
     
    -  404   -
         /**
    -  405   -
          * Sets whether or not the analyzer is enabled.
    -  406   -
          *
    -  407   -
          * @param archiveAnalyzerEnabled the value of the new setting
    -  408   -
          */
    -  409   -
         public void setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) {
    -  410  0
             this.archiveAnalyzerEnabled = archiveAnalyzerEnabled;
    -  411  0
         }
    -  412   -
     
    -  413   -
         /**
    -  414  
          * Returns whether or not the analyzer is enabled.
    -  415   +  400  
          *
    -  416   +  401  
          * @return true if the analyzer is enabled
    +  402   +
          */
    +  403   +
         public Boolean isJarAnalyzerEnabled() {
    +  404  0
             return jarAnalyzerEnabled;
    +  405   +
         }
    +  406   +
     
    +  407   +
         /**
    +  408   +
          * Sets whether or not the analyzer is enabled.
    +  409   +
          *
    +  410   +
          * @param jarAnalyzerEnabled the value of the new setting
    +  411   +
          */
    +  412   +
         public void setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) {
    +  413  0
             this.jarAnalyzerEnabled = jarAnalyzerEnabled;
    +  414  0
         }
    +  415   +
         /**
    +  416   +
          * Whether or not the Archive Analyzer is enabled.
     417  
          */
     418   -
         public Boolean isAssemblyAnalyzerEnabled() {
    -  419  0
             return assemblyAnalyzerEnabled;
    +
         private Boolean archiveAnalyzerEnabled;
    +  419   +
     
     420   -
         }
    +
         /**
     421   -
     
    -  422   -
         /**
    -  423   -
          * Sets whether or not the analyzer is enabled.
    -  424   -
          *
    -  425   -
          * @param assemblyAnalyzerEnabled the value of the new setting
    -  426   -
          */
    -  427   -
         public void setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) {
    -  428  0
             this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled;
    -  429  0
         }
    -  430   -
         /**
    -  431   -
          * Whether or not the .NET Nuspec Analyzer is enabled.
    -  432   -
          */
    -  433   -
         private Boolean nuspecAnalyzerEnabled;
    -  434   -
     
    -  435   -
         /**
    -  436  
          * Returns whether or not the analyzer is enabled.
    -  437   +  422  
          *
    -  438   +  423  
          * @return true if the analyzer is enabled
    -  439   +  424  
          */
    -  440   -
         public Boolean isNuspecAnalyzerEnabled() {
    -  441  0
             return nuspecAnalyzerEnabled;
    -  442   +  425   +
         public Boolean isArchiveAnalyzerEnabled() {
    +  426  0
             return archiveAnalyzerEnabled;
    +  427  
         }
    -  443   -
     
    -  444   +  428  
         /**
    -  445   +  429   +
          * Whether or not the .NET Assembly Analyzer is enabled.
    +  430   +
          */
    +  431   +
         private Boolean assemblyAnalyzerEnabled;
    +  432   +
     
    +  433   +
         /**
    +  434  
          * Sets whether or not the analyzer is enabled.
    -  446   +  435  
          *
    -  447   -
          * @param nuspecAnalyzerEnabled the value of the new setting
    -  448   +  436   +
          * @param archiveAnalyzerEnabled the value of the new setting
    +  437  
          */
    -  449   -
         public void setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) {
    -  450  0
             this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled;
    -  451  0
         }
    -  452   -
         /**
    -  453   -
          * Whether or not the PHP Composer Analyzer is enabled.
    -  454   -
          */
    -  455   -
         private Boolean composerAnalyzerEnabled;
    -  456   +  438   +
         public void setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) {
    +  439  0
             this.archiveAnalyzerEnabled = archiveAnalyzerEnabled;
    +  440  0
         }
    +  441  
     
    -  457   +  442  
         /**
    -  458   -
          * Get the value of composerAnalyzerEnabled.
    -  459   +  443   +
          * Returns whether or not the analyzer is enabled.
    +  444  
          *
    +  445   +
          * @return true if the analyzer is enabled
    +  446   +
          */
    +  447   +
         public Boolean isAssemblyAnalyzerEnabled() {
    +  448  0
             return assemblyAnalyzerEnabled;
    +  449   +
         }
    +  450   +
     
    +  451   +
         /**
    +  452   +
          * Sets whether or not the analyzer is enabled.
    +  453   +
          *
    +  454   +
          * @param assemblyAnalyzerEnabled the value of the new setting
    +  455   +
          */
    +  456   +
         public void setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) {
    +  457  0
             this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled;
    +  458  0
         }
    +  459   +
         /**
     460   -
          * @return the value of composerAnalyzerEnabled
    +
          * Whether or not the .NET Nuspec Analyzer is enabled.
     461  
          */
     462   -
         public Boolean isComposerAnalyzerEnabled() {
    -  463  0
             return composerAnalyzerEnabled;
    +
         private Boolean nuspecAnalyzerEnabled;
    +  463   +
     
     464   -
         }
    +
         /**
     465   -
     
    +
          * Returns whether or not the analyzer is enabled.
     466   -
         /**
    +
          *
     467   -
          * Set the value of composerAnalyzerEnabled.
    +
          * @return true if the analyzer is enabled
     468   -
          *
    +
          */
     469   -
          * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled
    -  470   -
          */
    +
         public Boolean isNuspecAnalyzerEnabled() {
    +  470  0
             return nuspecAnalyzerEnabled;
     471   -
         public void setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) {
    -  472  0
             this.composerAnalyzerEnabled = composerAnalyzerEnabled;
    -  473  0
         }
    -  474   -
         /**
    -  475   -
          * Whether the autoconf analyzer should be enabled.
    -  476   -
          */
    -  477   -
         private Boolean autoconfAnalyzerEnabled;
    -  478   +
         }
    +  472  
     
    -  479   +  473  
         /**
    -  480   -
          * Get the value of autoconfAnalyzerEnabled.
    -  481   +  474   +
          * Sets whether or not the analyzer is enabled.
    +  475  
          *
    +  476   +
          * @param nuspecAnalyzerEnabled the value of the new setting
    +  477   +
          */
    +  478   +
         public void setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) {
    +  479  0
             this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled;
    +  480  0
         }
    +  481   +
         /**
     482   -
          * @return the value of autoconfAnalyzerEnabled
    +
          * Whether or not the PHP Composer Analyzer is enabled.
     483  
          */
     484   -
         public Boolean isAutoconfAnalyzerEnabled() {
    -  485  0
             return autoconfAnalyzerEnabled;
    +
         private Boolean composerAnalyzerEnabled;
    +  485   +
     
     486   -
         }
    +
         /**
     487   -
     
    +
          * Get the value of composerAnalyzerEnabled.
     488   -
         /**
    +
          *
     489   -
          * Set the value of autoconfAnalyzerEnabled.
    +
          * @return the value of composerAnalyzerEnabled
     490   -
          *
    +
          */
     491   -
          * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled
    -  492   -
          */
    +
         public Boolean isComposerAnalyzerEnabled() {
    +  492  0
             return composerAnalyzerEnabled;
     493   -
         public void setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) {
    -  494  0
             this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled;
    -  495  0
         }
    -  496   -
         /**
    -  497   -
          * Whether the CMake analyzer should be enabled.
    -  498   -
          */
    -  499   -
         private Boolean cmakeAnalyzerEnabled;
    -  500   +
         }
    +  494  
     
    -  501   +  495  
         /**
    -  502   -
          * Get the value of cmakeAnalyzerEnabled.
    -  503   +  496   +
          * Set the value of composerAnalyzerEnabled.
    +  497  
          *
    +  498   +
          * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled
    +  499   +
          */
    +  500   +
         public void setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) {
    +  501  0
             this.composerAnalyzerEnabled = composerAnalyzerEnabled;
    +  502  0
         }
    +  503   +
         /**
     504   -
          * @return the value of cmakeAnalyzerEnabled
    +
          * Whether the autoconf analyzer should be enabled.
     505  
          */
     506   -
         public Boolean isCMakeAnalyzerEnabled() {
    -  507  0
             return cmakeAnalyzerEnabled;
    +
         private Boolean autoconfAnalyzerEnabled;
    +  507   +
     
     508   -
         }
    +
         /**
     509   -
     
    +
          * Get the value of autoconfAnalyzerEnabled.
     510   -
         /**
    +
          *
     511   -
          * Set the value of cmakeAnalyzerEnabled.
    +
          * @return the value of autoconfAnalyzerEnabled
     512   -
          *
    +
          */
     513   -
          * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled
    -  514   -
          */
    +
         public Boolean isAutoconfAnalyzerEnabled() {
    +  514  0
             return autoconfAnalyzerEnabled;
     515   -
         public void setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) {
    -  516  0
             this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled;
    -  517  0
         }
    -  518   -
         /**
    -  519   -
          * Whether or not the openssl analyzer is enabled.
    -  520   -
          */
    -  521   -
         private Boolean opensslAnalyzerEnabled;
    -  522   +
         }
    +  516  
     
    -  523   +  517  
         /**
    -  524   -
          * Get the value of opensslAnalyzerEnabled.
    -  525   +  518   +
          * Set the value of autoconfAnalyzerEnabled.
    +  519  
          *
    +  520   +
          * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled
    +  521   +
          */
    +  522   +
         public void setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) {
    +  523  0
             this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled;
    +  524  0
         }
    +  525   +
         /**
     526   -
          * @return the value of opensslAnalyzerEnabled
    +
          * Whether the CMake analyzer should be enabled.
     527  
          */
     528   -
         public Boolean isOpensslAnalyzerEnabled() {
    -  529  0
             return opensslAnalyzerEnabled;
    +
         private Boolean cmakeAnalyzerEnabled;
    +  529   +
     
     530   -
         }
    +
         /**
     531   -
     
    +
          * Get the value of cmakeAnalyzerEnabled.
     532   -
         /**
    +
          *
     533   -
          * Set the value of opensslAnalyzerEnabled.
    +
          * @return the value of cmakeAnalyzerEnabled
     534   -
          *
    +
          */
     535   -
          * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled
    -  536   -
          */
    +
         public Boolean isCMakeAnalyzerEnabled() {
    +  536  0
             return cmakeAnalyzerEnabled;
     537   -
         public void setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) {
    -  538  0
             this.opensslAnalyzerEnabled = opensslAnalyzerEnabled;
    -  539  0
         }
    -  540   -
         /**
    -  541   -
          * Whether or not the Node.js Analyzer is enabled.
    -  542   -
          */
    -  543   -
         private Boolean nodeAnalyzerEnabled;
    -  544   +
         }
    +  538  
     
    -  545   +  539  
         /**
    -  546   -
          * Get the value of nodeAnalyzerEnabled.
    -  547   +  540   +
          * Set the value of cmakeAnalyzerEnabled.
    +  541  
          *
    +  542   +
          * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled
    +  543   +
          */
    +  544   +
         public void setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) {
    +  545  0
             this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled;
    +  546  0
         }
    +  547   +
         /**
     548   -
          * @return the value of nodeAnalyzerEnabled
    +
          * Whether or not the openssl analyzer is enabled.
     549  
          */
     550   -
         public Boolean isNodeAnalyzerEnabled() {
    -  551  0
             return nodeAnalyzerEnabled;
    +
         private Boolean opensslAnalyzerEnabled;
    +  551   +
     
     552   -
         }
    +
         /**
     553   -
     
    +
          * Get the value of opensslAnalyzerEnabled.
     554   -
         /**
    +
          *
     555   -
          * Set the value of nodeAnalyzerEnabled.
    +
          * @return the value of opensslAnalyzerEnabled
     556   -
          *
    +
          */
     557   -
          * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled
    -  558   -
          */
    +
         public Boolean isOpensslAnalyzerEnabled() {
    +  558  0
             return opensslAnalyzerEnabled;
     559   -
         public void setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) {
    -  560  0
             this.nodeAnalyzerEnabled = nodeAnalyzerEnabled;
    -  561  0
         }
    -  562   -
         /**
    -  563   -
          * Whether the ruby gemspec analyzer should be enabled.
    -  564   -
          */
    -  565   -
         private Boolean rubygemsAnalyzerEnabled;
    -  566   +
         }
    +  560  
     
    -  567   +  561  
         /**
    -  568   -
          * Get the value of rubygemsAnalyzerEnabled.
    -  569   +  562   +
          * Set the value of opensslAnalyzerEnabled.
    +  563  
          *
    +  564   +
          * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled
    +  565   +
          */
    +  566   +
         public void setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) {
    +  567  0
             this.opensslAnalyzerEnabled = opensslAnalyzerEnabled;
    +  568  0
         }
    +  569   +
         /**
     570   -
          * @return the value of rubygemsAnalyzerEnabled
    +
          * Whether or not the Node.js Analyzer is enabled.
     571  
          */
     572   -
         public Boolean isRubygemsAnalyzerEnabled() {
    -  573  0
             return rubygemsAnalyzerEnabled;
    +
         private Boolean nodeAnalyzerEnabled;
    +  573   +
     
     574   -
         }
    +
         /**
     575   -
     
    +
          * Get the value of nodeAnalyzerEnabled.
     576   -
         /**
    +
          *
     577   -
          * Set the value of rubygemsAnalyzerEnabled.
    +
          * @return the value of nodeAnalyzerEnabled
     578   -
          *
    +
          */
     579   -
          * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled
    -  580   -
          */
    +
         public Boolean isNodeAnalyzerEnabled() {
    +  580  0
             return nodeAnalyzerEnabled;
     581   -
         public void setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) {
    -  582  0
             this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled;
    -  583  0
         }
    -  584   -
         /**
    -  585   -
          * Whether the python package analyzer should be enabled.
    -  586   -
          */
    -  587   -
         private Boolean pyPackageAnalyzerEnabled;
    -  588   +
         }
    +  582  
     
    -  589   +  583  
         /**
    -  590   -
          * Get the value of pyPackageAnalyzerEnabled.
    -  591   +  584   +
          * Set the value of nodeAnalyzerEnabled.
    +  585  
          *
    +  586   +
          * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled
    +  587   +
          */
    +  588   +
         public void setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) {
    +  589  0
             this.nodeAnalyzerEnabled = nodeAnalyzerEnabled;
    +  590  0
         }
    +  591   +
         /**
     592   -
          * @return the value of pyPackageAnalyzerEnabled
    +
          * Whether the ruby gemspec analyzer should be enabled.
     593  
          */
     594   -
         public Boolean isPyPackageAnalyzerEnabled() {
    -  595  0
             return pyPackageAnalyzerEnabled;
    +
         private Boolean rubygemsAnalyzerEnabled;
    +  595   +
     
     596   -
         }
    +
         /**
     597   -
     
    +
          * Get the value of rubygemsAnalyzerEnabled.
     598   -
         /**
    -  599   -
          * Set the value of pyPackageAnalyzerEnabled.
    -  600  
          *
    -  601   -
          * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled
    -  602   +  599   +
          * @return the value of rubygemsAnalyzerEnabled
    +  600  
          */
    +  601   +
         public Boolean isRubygemsAnalyzerEnabled() {
    +  602  0
             return rubygemsAnalyzerEnabled;
     603   -
         public void setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) {
    -  604  0
             this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled;
    -  605  0
         }
    -  606   +
         }
    +  604  
     
    -  607   +  605  
         /**
    +  606   +
          * Set the value of rubygemsAnalyzerEnabled.
    +  607   +
          *
     608   -
          * Whether the python distribution analyzer should be enabled.
    +
          * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled
     609  
          */
     610   -
         private Boolean pyDistributionAnalyzerEnabled;
    -  611   -
     
    -  612   -
         /**
    +
         public void setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) {
    +  611  0
             this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled;
    +  612  0
         }
     613   -
          * Get the value of pyDistributionAnalyzerEnabled.
    +
         /**
     614   -
          *
    +
          * Whether the python package analyzer should be enabled.
     615   -
          * @return the value of pyDistributionAnalyzerEnabled
    +
          */
     616   -
          */
    +
         private Boolean pyPackageAnalyzerEnabled;
     617   -
         public Boolean isPyDistributionAnalyzerEnabled() {
    -  618  0
             return pyDistributionAnalyzerEnabled;
    +
     
    +  618   +
         /**
     619   -
         }
    +
          * Get the value of pyPackageAnalyzerEnabled.
     620   -
     
    +
          *
     621   -
         /**
    +
          * @return the value of pyPackageAnalyzerEnabled
     622   -
          * Set the value of pyDistributionAnalyzerEnabled.
    +
          */
     623   -
          *
    -  624   -
          * @param pyDistributionAnalyzerEnabled new value of pyDistributionAnalyzerEnabled
    +
         public Boolean isPyPackageAnalyzerEnabled() {
    +  624  0
             return pyPackageAnalyzerEnabled;
     625   -
          */
    -  626   -
         public void setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) {
    -  627  0
             this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled;
    -  628  0
         }
    -  629   -
     
    -  630   -
         /**
    -  631   -
          * Whether or not the central analyzer is enabled.
    -  632   -
          */
    -  633   -
         private Boolean centralAnalyzerEnabled;
    -  634   -
     
    -  635   -
         /**
    -  636   -
          * Get the value of centralAnalyzerEnabled.
    -  637   -
          *
    -  638   -
          * @return the value of centralAnalyzerEnabled
    -  639   -
          */
    -  640   -
         public Boolean isCentralAnalyzerEnabled() {
    -  641  0
             return centralAnalyzerEnabled;
    -  642  
         }
    -  643   +  626  
     
    -  644   +  627  
         /**
    -  645   -
          * Set the value of centralAnalyzerEnabled.
    -  646   +  628   +
          * Set the value of pyPackageAnalyzerEnabled.
    +  629  
          *
    -  647   -
          * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled
    -  648   +  630   +
          * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled
    +  631  
          */
    -  649   -
         public void setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) {
    -  650  0
             this.centralAnalyzerEnabled = centralAnalyzerEnabled;
    -  651  0
         }
    -  652   +  632   +
         public void setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) {
    +  633  0
             this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled;
    +  634  0
         }
    +  635  
     
    -  653   +  636  
         /**
    +  637   +
          * Whether the python distribution analyzer should be enabled.
    +  638   +
          */
    +  639   +
         private Boolean pyDistributionAnalyzerEnabled;
    +  640   +
     
    +  641   +
         /**
    +  642   +
          * Get the value of pyDistributionAnalyzerEnabled.
    +  643   +
          *
    +  644   +
          * @return the value of pyDistributionAnalyzerEnabled
    +  645   +
          */
    +  646   +
         public Boolean isPyDistributionAnalyzerEnabled() {
    +  647  0
             return pyDistributionAnalyzerEnabled;
    +  648   +
         }
    +  649   +
     
    +  650   +
         /**
    +  651   +
          * Set the value of pyDistributionAnalyzerEnabled.
    +  652   +
          *
    +  653   +
          * @param pyDistributionAnalyzerEnabled new value of
     654   -
          * Whether or not the nexus analyzer is enabled.
    +
          * pyDistributionAnalyzerEnabled
     655  
          */
     656   -
         private Boolean nexusAnalyzerEnabled;
    -  657   -
     
    -  658   -
         /**
    +
         public void setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) {
    +  657  0
             this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled;
    +  658  0
         }
     659   -
          * Get the value of nexusAnalyzerEnabled.
    +
     
     660   -
          *
    +
         /**
     661   -
          * @return the value of nexusAnalyzerEnabled
    +
          * Whether or not the central analyzer is enabled.
     662  
          */
     663   -
         public Boolean isNexusAnalyzerEnabled() {
    -  664  0
             return nexusAnalyzerEnabled;
    +
         private Boolean centralAnalyzerEnabled;
    +  664   +
     
     665   -
         }
    +
         /**
     666   -
     
    +
          * Get the value of centralAnalyzerEnabled.
     667   -
         /**
    -  668   -
          * Set the value of nexusAnalyzerEnabled.
    -  669  
          *
    -  670   -
          * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
    -  671   +  668   +
          * @return the value of centralAnalyzerEnabled
    +  669  
          */
    +  670   +
         public Boolean isCentralAnalyzerEnabled() {
    +  671  0
             return centralAnalyzerEnabled;
     672   -
         public void setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) {
    -  673  0
             this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
    -  674  0
         }
    -  675   +
         }
    +  673  
     
    -  676   +  674  
         /**
    +  675   +
          * Set the value of centralAnalyzerEnabled.
    +  676   +
          *
     677   -
          * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local).
    +
          * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled
     678  
          */
     679   -
         private String nexusUrl;
    -  680   -
     
    -  681   -
         /**
    +
         public void setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) {
    +  680  0
             this.centralAnalyzerEnabled = centralAnalyzerEnabled;
    +  681  0
         }
     682   -
          * Get the value of nexusUrl.
    +
     
     683   -
          *
    +
         /**
     684   -
          * @return the value of nexusUrl
    +
          * Whether or not the nexus analyzer is enabled.
     685  
          */
     686   -
         public String getNexusUrl() {
    -  687  0
             return nexusUrl;
    +
         private Boolean nexusAnalyzerEnabled;
    +  687   +
     
     688   -
         }
    +
         /**
     689   -
     
    +
          * Get the value of nexusAnalyzerEnabled.
     690   -
         /**
    +
          *
     691   -
          * Set the value of nexusUrl.
    +
          * @return the value of nexusAnalyzerEnabled
     692   -
          *
    +
          */
     693   -
          * @param nexusUrl new value of nexusUrl
    -  694   -
          */
    +
         public Boolean isNexusAnalyzerEnabled() {
    +  694  0
             return nexusAnalyzerEnabled;
     695   -
         public void setNexusUrl(String nexusUrl) {
    -  696  0
             this.nexusUrl = nexusUrl;
    -  697  0
         }
    -  698   -
         /**
    -  699   -
          * Whether or not the defined proxy should be used when connecting to Nexus.
    -  700   -
          */
    -  701   -
         private Boolean nexusUsesProxy;
    -  702   -
     
    -  703   -
         /**
    -  704   -
          * Get the value of nexusUsesProxy.
    -  705   -
          *
    -  706   -
          * @return the value of nexusUsesProxy
    -  707   -
          */
    -  708   -
         public Boolean isNexusUsesProxy() {
    -  709  0
             return nexusUsesProxy;
    -  710  
         }
    +  696   +
     
    +  697   +
         /**
    +  698   +
          * Set the value of nexusAnalyzerEnabled.
    +  699   +
          *
    +  700   +
          * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
    +  701   +
          */
    +  702   +
         public void setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) {
    +  703  0
             this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
    +  704  0
         }
    +  705   +
     
    +  706   +
         /**
    +  707   +
          * The URL of a Nexus server's REST API end point
    +  708   +
          * (http://domain/nexus/service/local).
    +  709   +
          */
    +  710   +
         private String nexusUrl;
     711  
     
     712  
         /**
     713   -
          * Set the value of nexusUsesProxy.
    +
          * Get the value of nexusUrl.
     714  
          *
     715   -
          * @param nexusUsesProxy new value of nexusUsesProxy
    +
          * @return the value of nexusUrl
     716  
          */
     717   -
         public void setNexusUsesProxy(Boolean nexusUsesProxy) {
    -  718  0
             this.nexusUsesProxy = nexusUsesProxy;
    -  719  0
         }
    +
         public String getNexusUrl() {
    +  718  0
             return nexusUrl;
    +  719   +
         }
     720  
     
     721  
         /**
     722   -
          * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP
    +
          * Set the value of nexusUrl.
     723   -
          * files.
    -  724   -
          */
    -  725   -
         private String zipExtensions;
    -  726   -
     
    -  727   -
         /**
    -  728   -
          * Get the value of zipExtensions.
    -  729  
          *
    +  724   +
          * @param nexusUrl new value of nexusUrl
    +  725   +
          */
    +  726   +
         public void setNexusUrl(String nexusUrl) {
    +  727  0
             this.nexusUrl = nexusUrl;
    +  728  0
         }
    +  729   +
         /**
     730   -
          * @return the value of zipExtensions
    +
          * Whether or not the defined proxy should be used when connecting to Nexus.
     731  
          */
     732   -
         public String getZipExtensions() {
    -  733  0
             return zipExtensions;
    +
         private Boolean nexusUsesProxy;
    +  733   +
     
     734   -
         }
    +
         /**
     735   -
     
    +
          * Get the value of nexusUsesProxy.
     736   -
         /**
    -  737   -
          * Set the value of zipExtensions.
    -  738  
          *
    -  739   -
          * @param zipExtensions new value of zipExtensions
    -  740   +  737   +
          * @return the value of nexusUsesProxy
    +  738  
          */
    +  739   +
         public Boolean isNexusUsesProxy() {
    +  740  0
             return nexusUsesProxy;
     741   -
         public void setZipExtensions(String zipExtensions) {
    -  742  0
             this.zipExtensions = zipExtensions;
    -  743  0
         }
    -  744   +
         }
    +  742  
     
    -  745   +  743  
         /**
    +  744   +
          * Set the value of nexusUsesProxy.
    +  745   +
          *
     746   -
          * The path to Mono for .NET assembly analysis on non-windows systems.
    +
          * @param nexusUsesProxy new value of nexusUsesProxy
     747  
          */
     748   -
         private String pathToMono;
    -  749   -
     
    -  750   -
         /**
    +
         public void setNexusUsesProxy(Boolean nexusUsesProxy) {
    +  749  0
             this.nexusUsesProxy = nexusUsesProxy;
    +  750  0
         }
     751   -
          * Get the value of pathToMono.
    +
     
     752   -
          *
    +
         /**
     753   -
          * @return the value of pathToMono
    +
          * Additional ZIP File extensions to add analyze. This should be a
     754   -
          */
    +
          * comma-separated list of file extensions to treat like ZIP files.
     755   -
         public String getPathToMono() {
    -  756  0
             return pathToMono;
    +
          */
    +  756   +
         private String zipExtensions;
     757   -
         }
    +
     
     758   -
     
    +
         /**
     759   -
         /**
    +
          * Get the value of zipExtensions.
     760   -
          * Set the value of pathToMono.
    +
          *
     761   -
          *
    +
          * @return the value of zipExtensions
     762   -
          * @param pathToMono new value of pathToMono
    +
          */
     763   -
          */
    -  764   -
         public void setPathToMono(String pathToMono) {
    -  765  0
             this.pathToMono = pathToMono;
    -  766  0
         }
    -  767   -
     
    -  768   -
         @Override
    -  769   -
         public void execute() throws BuildException {
    -  770  4
             dealWithReferences();
    -  771  4
             validateConfiguration();
    -  772  3
             populateSettings();
    -  773  3
             Engine engine = null;
    -  774   -
             try {
    -  775  3
                 engine = new Engine(Check.class.getClassLoader());
    -  776  3
                 if (isUpdateOnly()) {
    -  777  0
                     log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN);
    -  778  0
                     engine.doUpdates();
    -  779   -
                 } else {
    -  780   -
                     try {
    -  781  3
                         for (Resource resource : path) {
    -  782  5
                             final FileProvider provider = resource.as(FileProvider.class);
    -  783  5
                             if (provider != null) {
    -  784  5
                                 final File file = provider.getFile();
    -  785  5
                                 if (file != null && file.exists()) {
    -  786  4
                                     engine.scan(file);
    -  787   -
                                 }
    -  788   -
                             }
    -  789  5
                         }
    -  790   -
     
    -  791  3
                         engine.analyzeDependencies();
    -  792  3
                         DatabaseProperties prop = null;
    -  793  3
                         CveDB cve = null;
    -  794   -
                         try {
    -  795  3
                             cve = new CveDB();
    -  796  3
                             cve.open();
    -  797  3
                             prop = cve.getDatabaseProperties();
    -  798  0
                         } catch (DatabaseException ex) {
    -  799  0
                             log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG);
    -  800   -
                         } finally {
    -  801  3
                             if (cve != null) {
    -  802  3
                                 cve.close();
    -  803   -
                             }
    -  804   -
                         }
    -  805  3
                         final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop);
    -  806  3
                         reporter.generateReports(reportOutputDirectory, reportFormat);
    -  807   -
     
    -  808  3
                         if (this.failBuildOnCVSS <= 10) {
    -  809  0
                             checkForFailure(engine.getDependencies());
    -  810   -
                         }
    -  811  3
                         if (this.showSummary) {
    -  812  3
                             showSummary(engine.getDependencies());
    -  813   -
                         }
    -  814  0
                     } catch (IOException ex) {
    -  815  0
                         log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG);
    -  816  0
                         throw new BuildException("Unable to generate dependency-check report", ex);
    -  817  0
                     } catch (Exception ex) {
    -  818  0
                         log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG);
    -  819  0
                         throw new BuildException("An exception occurred; unable to continue task", ex);
    -  820  3
                     }
    -  821   -
                 }
    -  822  0
             } catch (DatabaseException ex) {
    -  823  0
                 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR);
    -  824   -
             } finally {
    -  825  3
                 Settings.cleanup(true);
    -  826  3
                 if (engine != null) {
    -  827  3
                     engine.cleanup();
    -  828   -
                 }
    -  829   -
             }
    -  830  3
         }
    -  831   -
     
    -  832   -
         /**
    -  833   -
          * Validate the configuration to ensure the parameters have been properly configured/initialized.
    -  834   -
          *
    -  835   -
          * @throws BuildException if the task was not configured correctly.
    -  836   -
          */
    -  837   -
         private void validateConfiguration() throws BuildException {
    -  838  4
             if (path == null) {
    -  839  1
                 throw new BuildException("No project dependencies have been defined to analyze.");
    -  840   -
             }
    -  841  3
             if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) {
    -  842  0
                 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11.");
    -  843   -
             }
    -  844  3
         }
    -  845   -
     
    -  846   -
         /**
    -  847   -
          * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
    -  848   -
          * required to change the proxy server, port, and connection timeout.
    -  849   -
          *
    -  850   -
          * @throws BuildException thrown when an invalid setting is configured.
    -  851   -
          */
    -  852   -
         @Override
    -  853   -
         protected void populateSettings() throws BuildException {
    -  854  3
             super.populateSettings();
    -  855  3
             Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
    -  856  3
             Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
    -  857  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
    -  858  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled);
    -  859  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled);
    -  860  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled);
    -  861  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled);
    -  862  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled);
    -  863  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled);
    -  864  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled);
    -  865  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled);
    -  866  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
    -  867  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
    -  868  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
    -  869  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
    -  870  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
    -  871  3
             Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
    -  872  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
    -  873  3
             Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
    -  874  3
             Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
    -  875  3
         }
    -  876   -
     
    -  877   -
         /**
    -  878   -
          * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the
    -  879   -
          * configuration.
    -  880   -
          *
    -  881   -
          * @param dependencies the list of dependency objects
    -  882   -
          * @throws BuildException thrown if a CVSS score is found that is higher then the threshold set
    -  883   -
          */
    -  884   -
         private void checkForFailure(List<Dependency> dependencies) throws BuildException {
    -  885  0
             final StringBuilder ids = new StringBuilder();
    -  886  0
             for (Dependency d : dependencies) {
    -  887  0
                 for (Vulnerability v : d.getVulnerabilities()) {
    -  888  0
                     if (v.getCvssScore() >= failBuildOnCVSS) {
    -  889  0
                         if (ids.length() == 0) {
    -  890  0
                             ids.append(v.getName());
    -  891   -
                         } else {
    -  892  0
                             ids.append(", ").append(v.getName());
    -  893   -
                         }
    -  894   -
                     }
    -  895  0
                 }
    -  896  0
             }
    -  897  0
             if (ids.length() > 0) {
    -  898  0
                 final String msg = String.format("%n%nDependency-Check Failure:%n"
    -  899   -
                         + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
    -  900  0
                         + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
    -  901  0
                 throw new BuildException(msg);
    -  902   -
             }
    -  903  0
         }
    -  904   -
     
    -  905   -
         /**
    -  906   -
          * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries.
    -  907   -
          *
    -  908   -
          * @param dependencies a list of dependency objects
    -  909   -
          */
    -  910   -
         private void showSummary(List<Dependency> dependencies) {
    -  911  3
             final StringBuilder summary = new StringBuilder();
    -  912  3
             for (Dependency d : dependencies) {
    -  913  5
                 boolean firstEntry = true;
    -  914  5
                 final StringBuilder ids = new StringBuilder();
    -  915  5
                 for (Vulnerability v : d.getVulnerabilities()) {
    -  916  8
                     if (firstEntry) {
    -  917  2
                         firstEntry = false;
    -  918   -
                     } else {
    -  919  6
                         ids.append(", ");
    -  920   -
                     }
    -  921  8
                     ids.append(v.getName());
    -  922  8
                 }
    -  923  5
                 if (ids.length() > 0) {
    -  924  2
                     summary.append(d.getFileName()).append(" (");
    -  925  2
                     firstEntry = true;
    -  926  2
                     for (Identifier id : d.getIdentifiers()) {
    -  927  5
                         if (firstEntry) {
    -  928  2
                             firstEntry = false;
    -  929   -
                         } else {
    -  930  3
                             summary.append(", ");
    -  931   -
                         }
    -  932  5
                         summary.append(id.getValue());
    -  933  5
                     }
    -  934  2
                     summary.append(") : ").append(ids).append(NEW_LINE);
    -  935   -
                 }
    -  936  5
             }
    -  937  3
             if (summary.length() > 0) {
    -  938  2
                 final String msg = String.format("%n%n"
    -  939   -
                         + "One or more dependencies were identified with known vulnerabilities:%n%n%s"
    -  940  1
                         + "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
    -  941  1
                 log(msg, Project.MSG_WARN);
    -  942   -
             }
    -  943  3
         }
    -  944   -
     
    -  945   -
         /**
    -  946   -
          * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", etc..
    -  947   -
          */
    -  948  4
         public static class ReportFormats extends EnumeratedAttribute {
    -  949   -
     
    -  950   -
             /**
    -  951   -
              * Returns the list of values for the report format.
    -  952   -
              *
    -  953   -
              * @return the list of values for the report format
    -  954   -
              */
    -  955   -
             @Override
    -  956   -
             public String[] getValues() {
    -  957  4
                 int i = 0;
    -  958  4
                 final Format[] formats = Format.values();
    -  959  4
                 final String[] values = new String[formats.length];
    -  960  20
                 for (Format format : formats) {
    -  961  16
                     values[i++] = format.name();
    -  962   -
                 }
    -  963  4
                 return values;
    -  964   -
             }
    -  965   +
         public String getZipExtensions() {
    +  764  0
             return zipExtensions;
    +  765  
         }
    -  966   +  766   +
     
    +  767   +
         /**
    +  768   +
          * Set the value of zipExtensions.
    +  769   +
          *
    +  770   +
          * @param zipExtensions new value of zipExtensions
    +  771   +
          */
    +  772   +
         public void setZipExtensions(String zipExtensions) {
    +  773  0
             this.zipExtensions = zipExtensions;
    +  774  0
         }
    +  775   +
     
    +  776   +
         /**
    +  777   +
          * The path to Mono for .NET assembly analysis on non-windows systems.
    +  778   +
          */
    +  779   +
         private String pathToMono;
    +  780   +
     
    +  781   +
         /**
    +  782   +
          * Get the value of pathToMono.
    +  783   +
          *
    +  784   +
          * @return the value of pathToMono
    +  785   +
          */
    +  786   +
         public String getPathToMono() {
    +  787  0
             return pathToMono;
    +  788   +
         }
    +  789   +
     
    +  790   +
         /**
    +  791   +
          * Set the value of pathToMono.
    +  792   +
          *
    +  793   +
          * @param pathToMono new value of pathToMono
    +  794   +
          */
    +  795   +
         public void setPathToMono(String pathToMono) {
    +  796  0
             this.pathToMono = pathToMono;
    +  797  0
         }
    +  798   +
     
    +  799   +
         @Override
    +  800   +
         public void execute() throws BuildException {
    +  801  8
             dealWithReferences();
    +  802  8
             validateConfiguration();
    +  803  6
             populateSettings();
    +  804  6
             Engine engine = null;
    +  805   +
             try {
    +  806  6
                 engine = new Engine(Check.class.getClassLoader());
    +  807  6
                 if (isUpdateOnly()) {
    +  808  0
                     log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN);
    +  809  0
                     engine.doUpdates();
    +  810   +
                 } else {
    +  811   +
                     try {
    +  812  6
                         for (Resource resource : path) {
    +  813  10
                             final FileProvider provider = resource.as(FileProvider.class);
    +  814  10
                             if (provider != null) {
    +  815  10
                                 final File file = provider.getFile();
    +  816  10
                                 if (file != null && file.exists()) {
    +  817  8
                                     engine.scan(file);
    +  818   +
                                 }
    +  819   +
                             }
    +  820  10
                         }
    +  821   +
     
    +  822  6
                         engine.analyzeDependencies();
    +  823  6
                         DatabaseProperties prop = null;
    +  824  6
                         CveDB cve = null;
    +  825   +
                         try {
    +  826  6
                             cve = new CveDB();
    +  827  6
                             cve.open();
    +  828  6
                             prop = cve.getDatabaseProperties();
    +  829  0
                         } catch (DatabaseException ex) {
    +  830  0
                             log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG);
    +  831   +
                         } finally {
    +  832  6
                             if (cve != null) {
    +  833  6
                                 cve.close();
    +  834   +
                             }
    +  835   +
                         }
    +  836  6
                         final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop);
    +  837  6
                         reporter.generateReports(reportOutputDirectory, reportFormat);
    +  838   +
     
    +  839  6
                         if (this.failBuildOnCVSS <= 10) {
    +  840  0
                             checkForFailure(engine.getDependencies());
    +  841   +
                         }
    +  842  6
                         if (this.showSummary) {
    +  843  6
                             showSummary(engine.getDependencies());
    +  844   +
                         }
    +  845  0
                     } catch (IOException ex) {
    +  846  0
                         log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG);
    +  847  0
                         throw new BuildException("Unable to generate dependency-check report", ex);
    +  848  0
                     } catch (Exception ex) {
    +  849  0
                         log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG);
    +  850  0
                         throw new BuildException("An exception occurred; unable to continue task", ex);
    +  851  6
                     }
    +  852   +
                 }
    +  853  0
             } catch (DatabaseException ex) {
    +  854  0
                 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR);
    +  855   +
             } finally {
    +  856  6
                 Settings.cleanup(true);
    +  857  6
                 if (engine != null) {
    +  858  6
                     engine.cleanup();
    +  859   +
                 }
    +  860   +
             }
    +  861  6
         }
    +  862   +
     
    +  863   +
         /**
    +  864   +
          * Validate the configuration to ensure the parameters have been properly
    +  865   +
          * configured/initialized.
    +  866   +
          *
    +  867   +
          * @throws BuildException if the task was not configured correctly.
    +  868   +
          */
    +  869   +
         private void validateConfiguration() throws BuildException {
    +  870  8
             if (path == null) {
    +  871  2
                 throw new BuildException("No project dependencies have been defined to analyze.");
    +  872   +
             }
    +  873  6
             if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) {
    +  874  0
                 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11.");
    +  875   +
             }
    +  876  6
         }
    +  877   +
     
    +  878   +
         /**
    +  879   +
          * Takes the properties supplied and updates the dependency-check settings.
    +  880   +
          * Additionally, this sets the system properties required to change the
    +  881   +
          * proxy server, port, and connection timeout.
    +  882   +
          *
    +  883   +
          * @throws BuildException thrown when an invalid setting is configured.
    +  884   +
          */
    +  885   +
         @Override
    +  886   +
         protected void populateSettings() throws BuildException {
    +  887  6
             super.populateSettings();
    +  888  6
             Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
    +  889  6
             Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
    +  890  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental);
    +  891  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
    +  892  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled);
    +  893  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled);
    +  894  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled);
    +  895  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled);
    +  896  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled);
    +  897  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled);
    +  898  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled);
    +  899  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled);
    +  900  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
    +  901  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
    +  902  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
    +  903  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
    +  904  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
    +  905  6
             Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
    +  906  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
    +  907  6
             Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
    +  908  6
             Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
    +  909  6
         }
    +  910   +
     
    +  911   +
         /**
    +  912   +
          * Checks to see if a vulnerability has been identified with a CVSS score
    +  913   +
          * that is above the threshold set in the configuration.
    +  914   +
          *
    +  915   +
          * @param dependencies the list of dependency objects
    +  916   +
          * @throws BuildException thrown if a CVSS score is found that is higher
    +  917   +
          * then the threshold set
    +  918   +
          */
    +  919   +
         private void checkForFailure(List<Dependency> dependencies) throws BuildException {
    +  920  0
             final StringBuilder ids = new StringBuilder();
    +  921  0
             for (Dependency d : dependencies) {
    +  922  0
                 for (Vulnerability v : d.getVulnerabilities()) {
    +  923  0
                     if (v.getCvssScore() >= failBuildOnCVSS) {
    +  924  0
                         if (ids.length() == 0) {
    +  925  0
                             ids.append(v.getName());
    +  926   +
                         } else {
    +  927  0
                             ids.append(", ").append(v.getName());
    +  928   +
                         }
    +  929   +
                     }
    +  930  0
                 }
    +  931  0
             }
    +  932  0
             if (ids.length() > 0) {
    +  933  0
                 final String msg = String.format("%n%nDependency-Check Failure:%n"
    +  934   +
                         + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
    +  935  0
                         + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
    +  936  0
                 throw new BuildException(msg);
    +  937   +
             }
    +  938  0
         }
    +  939   +
     
    +  940   +
         /**
    +  941   +
          * Generates a warning message listing a summary of dependencies and their
    +  942   +
          * associated CPE and CVE entries.
    +  943   +
          *
    +  944   +
          * @param dependencies a list of dependency objects
    +  945   +
          */
    +  946   +
         private void showSummary(List<Dependency> dependencies) {
    +  947  6
             final StringBuilder summary = new StringBuilder();
    +  948  6
             for (Dependency d : dependencies) {
    +  949  10
                 boolean firstEntry = true;
    +  950  10
                 final StringBuilder ids = new StringBuilder();
    +  951  10
                 for (Vulnerability v : d.getVulnerabilities()) {
    +  952  36
                     if (firstEntry) {
    +  953  8
                         firstEntry = false;
    +  954   +
                     } else {
    +  955  28
                         ids.append(", ");
    +  956   +
                     }
    +  957  36
                     ids.append(v.getName());
    +  958  36
                 }
    +  959  10
                 if (ids.length() > 0) {
    +  960  8
                     summary.append(d.getFileName()).append(" (");
    +  961  8
                     firstEntry = true;
    +  962  8
                     for (Identifier id : d.getIdentifiers()) {
    +  963  30
                         if (firstEntry) {
    +  964  8
                             firstEntry = false;
    +  965   +
                         } else {
    +  966  22
                             summary.append(", ");
    +  967   +
                         }
    +  968  30
                         summary.append(id.getValue());
    +  969  30
                     }
    +  970  8
                     summary.append(") : ").append(ids).append(NEW_LINE);
    +  971   +
                 }
    +  972  10
             }
    +  973  6
             if (summary.length() > 0) {
    +  974  12
                 final String msg = String.format("%n%n"
    +  975   +
                         + "One or more dependencies were identified with known vulnerabilities:%n%n%s"
    +  976  6
                         + "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
    +  977  6
                 log(msg, Project.MSG_WARN);
    +  978   +
             }
    +  979  6
         }
    +  980   +
     
    +  981   +
         /**
    +  982   +
          * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN",
    +  983   +
          * etc..
    +  984   +
          */
    +  985  8
         public static class ReportFormats extends EnumeratedAttribute {
    +  986   +
     
    +  987   +
             /**
    +  988   +
              * Returns the list of values for the report format.
    +  989   +
              *
    +  990   +
              * @return the list of values for the report format
    +  991   +
              */
    +  992   +
             @Override
    +  993   +
             public String[] getValues() {
    +  994  8
                 int i = 0;
    +  995  8
                 final Format[] formats = Format.values();
    +  996  8
                 final String[] values = new String[formats.length];
    +  997  40
                 for (Format format : formats) {
    +  998  32
                     values[i++] = format.name();
    +  999   +
                 }
    +  1000  8
                 return values;
    +  1001   +
             }
    +  1002   +
         }
    +  1003  
     }
    - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Purge.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Purge.html index 2e8b98fd9..edf8c1e15 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Purge.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Purge.html @@ -105,13 +105,13 @@
          */
     44  
         public Purge() {
    -  45  4
             super();
    +  45  8
             super();
     46  
             // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
     47  
             // core end up coming through this tasks logger
    -  48  4
             StaticLoggerBinder.getSingleton().setTask(this);
    -  49  4
         }
    +  48  8
             StaticLoggerBinder.getSingleton().setTask(this);
    +  49  8
         }
     50  
     
     51   @@ -120,7 +120,7 @@
          * The location of the data directory that contains
     53  
          */
    -  54  4
         private String dataDirectory = null;
    +  54  8
         private String dataDirectory = null;
     55  
     
     56   @@ -198,43 +198,43 @@
          */
     100  
         protected void populateSettings() {
    -  101  3
             Settings.initialize();
    -  102  3
             InputStream taskProperties = null;
    +  101  6
             Settings.initialize();
    +  102  6
             InputStream taskProperties = null;
     103  
             try {
    -  104  3
                 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
    -  105  3
                 Settings.mergeProperties(taskProperties);
    +  104  6
                 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
    +  105  6
                 Settings.mergeProperties(taskProperties);
     106  0
             } catch (IOException ex) {
     107  0
                 log("Unable to load the dependency-check ant task.properties file.", ex, Project.MSG_WARN);
     108  
             } finally {
    -  109  3
                 if (taskProperties != null) {
    +  109  6
                 if (taskProperties != null) {
     110  
                     try {
    -  111  3
                         taskProperties.close();
    +  111  6
                         taskProperties.close();
     112  0
                     } catch (IOException ex) {
     113  0
                         log("", ex, Project.MSG_DEBUG);
    -  114  3
                     }
    +  114  6
                     }
     115  
                 }
     116  
             }
    -  117  3
             if (dataDirectory != null) {
    +  117  6
             if (dataDirectory != null) {
     118  0
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
     119  
             } else {
    -  120  3
                 final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    -  121  3
                 final File base = jarPath.getParentFile();
    -  122  3
                 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
    -  123  3
                 final File dataDir = new File(base, sub);
    -  124  3
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
    +  120  6
                 final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    +  121  6
                 final File base = jarPath.getParentFile();
    +  122  6
                 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
    +  123  6
                 final File dataDir = new File(base, sub);
    +  124  6
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
     125  
             }
    -  126  3
         }
    +  126  6
         }
     127  
     }
    - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Update.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Update.html index 484e6c84c..474e7ce83 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Update.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Update.html @@ -91,13 +91,13 @@
          */
     37  
         public Update() {
    -  38  4
             super();
    +  38  8
             super();
     39  
             // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
     40  
             // core end up coming through this tasks logger
    -  41  4
             StaticLoggerBinder.getSingleton().setTask(this);
    -  42  4
         }
    +  41  8
             StaticLoggerBinder.getSingleton().setTask(this);
    +  42  8
         }
     43  
     
     44   @@ -785,22 +785,22 @@
         @Override
     413  
         protected void populateSettings() throws BuildException {
    -  414  3
             super.populateSettings();
    -  415  3
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
    -  416  3
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
    -  417  3
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
    -  418  3
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
    -  419  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
    -  420  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
    -  421  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
    -  422  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
    -  423  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
    -  424  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
    -  425  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
    -  426  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
    -  427  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
    -  428  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
    -  429  3
             if (cveValidForHours != null) {
    +  414  6
             super.populateSettings();
    +  415  6
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
    +  416  6
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
    +  417  6
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
    +  418  6
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
    +  419  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
    +  420  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
    +  421  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
    +  422  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
    +  423  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
    +  424  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
    +  425  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
    +  426  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
    +  427  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
    +  428  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
    +  429  6
             if (cveValidForHours != null) {
     430  0
                 if (cveValidForHours >= 0) {
     431  0
                     Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
     432   @@ -810,11 +810,11 @@
                 }
     435  
             }
    -  436  3
         }
    +  436  6
         }
     437  
     }
    - + diff --git a/dependency-check-ant/cobertura/org.slf4j.impl.StaticLoggerBinder.html b/dependency-check-ant/cobertura/org.slf4j.impl.StaticLoggerBinder.html index fdd8e0a27..3b263a180 100644 --- a/dependency-check-ant/cobertura/org.slf4j.impl.StaticLoggerBinder.html +++ b/dependency-check-ant/cobertura/org.slf4j.impl.StaticLoggerBinder.html @@ -68,150 +68,172 @@  25  
     /**
     26   -
      * The binding of org.slf4j.LoggerFactory class with an actual instance of org.slf4j.ILoggerFactory is performed using information
    +
      * The binding of org.slf4j.LoggerFactory class with an actual instance of
     27   -
      * returned by this class.
    +
      * org.slf4j.ILoggerFactory is performed using information returned by this
     28   -
      *
    +
      * class.
     29   -
      * @author colezlaw
    +
      *
     30   -
      */
    +
      * @author colezlaw
     31   -
     public class StaticLoggerBinder implements LoggerFactoryBinder {
    +
      */
     32   -
     
    +
     //CSOFF: FinalClass
     33   -
         /**
    +
     public class StaticLoggerBinder implements LoggerFactoryBinder {
     34   -
          * The unique instance of this class
    +
     //CSON: FinalClass
     35   -
          *
    +
     
     36   -
          */
    -  37  1
         private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
    +
         /**
    +  37   +
          * The unique instance of this class
     38   -
     
    -  39   -
         /**
    +
          */
    +  39  2
         private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
     40   -
          * Return the singleton of this class.
    +
     
     41   -
          *
    +
         /**
     42   -
          * @return the StaticLoggerBinder singleton
    +
          * Return the singleton of this class.
     43   -
          */
    -  44   -
         public static final StaticLoggerBinder getSingleton() {
    -  45  58
             return SINGLETON;
    -  46   -
         }
    -  47   -
     
    -  48   -
         /**
    -  49   -
          * Ant tasks have the log method we actually want to call. So we hang onto the task as a delegate
    -  50   -
          */
    -  51  1
         private Task task = null;
    -  52   -
     
    -  53   -
         /**
    -  54   -
          * Set the Task which will this is to log through.
    -  55  
          *
    +  44   +
          * @return the StaticLoggerBinder singleton
    +  45   +
          */
    +  46   +
         public static final StaticLoggerBinder getSingleton() {
    +  47  120
             return SINGLETON;
    +  48   +
         }
    +  49   +
     
    +  50   +
         /**
    +  51   +
          * Ant tasks have the log method we actually want to call. So we hang onto
    +  52   +
          * the task as a delegate
    +  53   +
          */
    +  54  2
         private Task task = null;
    +  55   +
     
     56   -
          * @param task the task through which to log
    +
         /**
     57   -
          */
    +
          * Set the Task which will this is to log through.
     58   +
          *
    +  59   +
          * @param task the task through which to log
    +  60   +
          */
    +  61  
         public void setTask(Task task) {
    -  59  12
             this.task = task;
    -  60  12
             loggerFactory = new AntLoggerFactory(task);
    -  61  12
         }
    -  62   -
     
    -  63   -
         /**
    -  64   -
          * Declare the version of the SLF4J API this implementation is compiled against. The value of this filed is usually modified
    +  62  24
             this.task = task;
    +  63  24
             loggerFactory = new AntLoggerFactory(task);
    +  64  24
         }
     65   -
          * with each release.
    +
     
     66   -
          */
    -  67   -
         // to avoid constant folding by the compiler, this field must *not* be final
    -  68  1
         public static String REQUESTED_API_VERSION = "1.7.12"; // final
    -  69   -
     
    -  70  1
         private static final String LOGGER_FACTORY_CLASS = AntLoggerFactory.class.getName();
    -  71   -
     
    -  72  
         /**
    -  73   -
          * The ILoggerFactory instance returned by the {@link #getLoggerFactory} method should always be the smae object
    -  74   +  67   +
          * Declare the version of the SLF4J API this implementation is compiled
    +  68   +
          * against. The value of this filed is usually modified with each release.
    +  69  
          */
    +  70   +
         // to avoid constant folding by the compiler, this field must *not* be final
    +  71   +
         //CSOFF: StaticVariableName
    +  72   +
         //CSOFF: VisibilityModifier
    +  73  2
         public static String REQUESTED_API_VERSION = "1.7.12"; // final
    +  74   +
         //CSON: VisibilityModifier
     75   -
         private ILoggerFactory loggerFactory;
    +
         //CSON: StaticVariableName
     76  
     
     77  
         /**
     78   -
          * Constructs a new static logger binder.
    +
          * The logger factory class string.
     79  
          */
    -  80  1
         private StaticLoggerBinder() {
    -  81  1
             loggerFactory = new AntLoggerFactory(task);
    -  82  1
         }
    +  80  2
         private static final String LOGGER_FACTORY_CLASS = AntLoggerFactory.class.getName();
    +  81   +
     
    +  82   +
         /**
     83   -
     
    +
          * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
     84   -
         /**
    +
          * method should always be the smae object
     85   -
          * Returns the logger factory.
    +
          */
     86   -
          *
    +
         private ILoggerFactory loggerFactory;
     87   -
          * @return the logger factory
    -  88   -
          */
    -  89   -
         @Override
    -  90   -
         public ILoggerFactory getLoggerFactory() {
    -  91  44
             return loggerFactory;
    -  92   -
         }
    -  93  
     
    -  94   +  88  
         /**
    -  95   -
          * Returns the logger factory class string.
    -  96   -
          *
    -  97   -
          * @return the logger factory class string
    -  98   +  89   +
          * Constructs a new static logger binder.
    +  90  
          */
    +  91  2
         private StaticLoggerBinder() {
    +  92  2
             loggerFactory = new AntLoggerFactory(task);
    +  93  2
         }
    +  94   +
     
    +  95   +
         /**
    +  96   +
          * Returns the logger factory.
    +  97   +
          *
    +  98   +
          * @return the logger factory
     99   -
         @Override
    +
          */
     100   -
         public String getLoggerFactoryClassStr() {
    -  101  1
             return LOGGER_FACTORY_CLASS;
    -  102   -
         }
    +
         @Override
    +  101   +
         public ILoggerFactory getLoggerFactory() {
    +  102  92
             return loggerFactory;
     103   +
         }
    +  104   +
     
    +  105   +
         /**
    +  106   +
          * Returns the logger factory class string.
    +  107   +
          *
    +  108   +
          * @return the logger factory class string
    +  109   +
          */
    +  110   +
         @Override
    +  111   +
         public String getLoggerFactoryClassStr() {
    +  112  2
             return LOGGER_FACTORY_CLASS;
    +  113   +
         }
    +  114  
     }
    - + diff --git a/dependency-check-ant/config-purge.html b/dependency-check-ant/config-purge.html index 59119b05f..997b4f2f8 100644 --- a/dependency-check-ant/config-purge.html +++ b/dependency-check-ant/config-purge.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Configuration @@ -52,7 +52,7 @@ @@ -138,9 +138,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/config-update.html b/dependency-check-ant/config-update.html index 4135946a2..d65e31734 100644 --- a/dependency-check-ant/config-update.html +++ b/dependency-check-ant/config-update.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Configuration @@ -52,7 +52,7 @@ @@ -138,9 +138,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/configuration.html b/dependency-check-ant/configuration.html index 0ea4d3453..27ea1ccc3 100644 --- a/dependency-check-ant/configuration.html +++ b/dependency-check-ant/configuration.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Configuration @@ -52,7 +52,7 @@ @@ -136,9 +136,6 @@ developed using - - - built on cloudbees @@ -174,7 +171,7 @@

    Configuration: dependency-check Task

    -

    The following properties can be set on the dependency-check-update task.

    +

    The following properties can be set on the dependency-check task.

    @@ -257,7 +254,7 @@ - + @@ -297,6 +294,15 @@ + + + + + + + + +
    proxyServer The Proxy Server. The Proxy Server; see the proxy configuration page for more information.  
     
    enableExperimental Enable the experimental analyzers. If not enabled the experimental analyzers (see below) will not be loaded or used. false

    Analyzer Configuration

    @@ -383,7 +389,7 @@ pyDistributionAnalyzerEnabled -Sets whether the Python Distribution Analyzer will be used. +Sets whether the experimental Python Distribution Analyzer will be used. true @@ -392,7 +398,7 @@ pyPackageAnalyzerEnabled -Sets whether the Python Package Analyzer will be used. +Sets whether the experimental Python Package Analyzer will be used. true @@ -401,7 +407,7 @@ rubygemsAnalyzerEnabled -Sets whether the Ruby Gemspec Analyzer will be used. +Sets whether the experimental Ruby Gemspec Analyzer will be used. true @@ -410,7 +416,7 @@ opensslAnalyzerEnabled -Sets whether or not the openssl Analyzer should be used. +Sets whether the openssl Analyzer should be used. true @@ -419,7 +425,7 @@ cmakeAnalyzerEnabled -Sets whether or not the CMake Analyzer should be used. +Sets whether the experimental CMake Analyzer should be used. true @@ -428,7 +434,7 @@ autoconfAnalyzerEnabled -Sets whether or not the autoconf Analyzer should be used. +Sets whether the experimental autoconf Analyzer should be used. true @@ -437,7 +443,7 @@ composerAnalyzerEnabled -Sets whether or not the PHP Composer Lock File Analyzer should be used. +Sets whether the experimental PHP Composer Lock File Analyzer should be used. true @@ -446,7 +452,7 @@ nodeAnalyzerEnabled -Sets whether or not the Node.js Analyzer should be used. +Sets whether the experimental Node.js Analyzer should be used. true @@ -455,7 +461,7 @@ nuspecAnalyzerEnabled -Sets whether or not the .NET Nuget Nuspec Analyzer will be used. +Sets whether the .NET Nuget Nuspec Analyzer will be used. true @@ -464,7 +470,7 @@ assemblyAnalyzerEnabled -Sets whether or not the .NET Assembly Analyzer should be used. +Sets whether the .NET Assembly Analyzer should be used. true diff --git a/dependency-check-ant/dependency-analysis.html b/dependency-check-ant/dependency-analysis.html index 7d24864ed..869c3ca7f 100644 --- a/dependency-check-ant/dependency-analysis.html +++ b/dependency-check-ant/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Dependencies Report @@ -52,7 +52,7 @@ @@ -215,9 +215,6 @@ developed using - - - built on cloudbees
    @@ -242,7 +239,7 @@ org.owasp dependency-check-core -1.3.6 +1.4.0 compile jar @@ -250,7 +247,7 @@ org.owasp dependency-check-utils -1.3.6 +1.4.0 compile jar @@ -258,7 +255,7 @@ org.owasp dependency-check-core -1.3.6 +1.4.0 test tests test-jar @@ -266,7 +263,7 @@ org.apache.ant ant -1.9.6 +1.9.7 provided jar @@ -274,7 +271,7 @@ org.apache.ant ant-testutil -1.9.6 +1.9.7 test jar diff --git a/dependency-check-ant/dependency-updates-report.html b/dependency-check-ant/dependency-updates-report.html index 28c9a7891..ca16efbef 100644 --- a/dependency-check-ant/dependency-updates-report.html +++ b/dependency-check-ant/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Dependency Updates Report @@ -52,7 +52,7 @@ @@ -215,9 +215,6 @@ developed using - - - built on cloudbees @@ -233,7 +230,7 @@ # of dependencies using the latest version available -23 +24 # of dependencies where the next version available is smaller than an incremental version update @@ -241,11 +238,11 @@ # of dependencies where the next version available is an incremental version update -3 +1 # of dependencies where the next version available is a minor version update -6 +7 # of dependencies where the next version available is a major version update @@ -353,7 +350,7 @@ commons-io commons-io -2.4 +2.5 jar @@ -377,7 +374,7 @@ org.apache.ant ant -1.9.6 +1.9.7 jar @@ -389,7 +386,7 @@ org.apache.ant ant-testutil -1.9.6 +1.9.7 jar @@ -470,39 +467,39 @@ 4.8.0 5.0.0 - + org.apache.maven maven-core -3.3.3 +3.3.9 jar -3.3.9 + - + org.apache.maven maven-plugin-api -3.3.3 +3.3.9 jar -3.3.9 + - + org.apache.maven maven-settings -3.3.3 +3.3.9 jar -3.3.9 + @@ -578,7 +575,7 @@ - + org.jmockit jmockit 1.22 @@ -587,18 +584,18 @@ jar - +1.23 - + org.jsoup jsoup -1.8.3 +1.9.1 jar - +1.9.2 @@ -668,7 +665,7 @@ org.owasp dependency-check-core -1.3.6 +1.4.0 compile jar @@ -680,7 +677,7 @@ org.owasp dependency-check-utils -1.3.6 +1.4.0 compile jar @@ -801,7 +798,7 @@ jar Newer versions -1.4.177 Next Minor
    1.4.178
    1.4.179
    1.4.180
    1.4.181
    1.4.182
    1.4.183
    1.4.184
    1.4.185
    1.4.186
    1.4.187
    1.4.188
    1.4.189
    1.4.190
    1.4.191 Latest Minor +1.4.177 Next Minor
    1.4.178
    1.4.179
    1.4.180
    1.4.181
    1.4.182
    1.4.183
    1.4.184
    1.4.185
    1.4.186
    1.4.187
    1.4.188
    1.4.189
    1.4.190
    1.4.191
    1.4.192 Latest Minor

    com.sun.mail:mailapi

    @@ -891,7 +888,7 @@ - + @@ -939,7 +936,7 @@ - + @@ -963,7 +960,7 @@ - + @@ -1050,7 +1047,7 @@ -
    commons-io
    Current Version2.4
    2.5
    Scope
    ant
    Current Version1.9.6
    1.9.7
    Scope
    ant-testutil
    Current Version1.9.6
    1.9.7
    Scope
    jar
    Newer versions4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    6.0.0 Latest Major
    +4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    6.0.0
    6.0.1 Latest Major

    org.apache.lucene:lucene-core

    @@ -1077,7 +1074,7 @@ -
    jar
    Newer versions4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    6.0.0 Latest Major
    +4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    6.0.0
    6.0.1 Latest Major

    org.apache.lucene:lucene-queryparser

    @@ -1104,7 +1101,7 @@ -
    jar
    Newer versions4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    6.0.0 Latest Major
    +4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    6.0.0
    6.0.1 Latest Major

    org.apache.lucene:lucene-test-framework

    @@ -1131,13 +1128,13 @@ -
    jar
    Newer versions4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    6.0.0 Latest Major
    +4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    6.0.0
    6.0.1 Latest Major

    org.apache.maven:maven-core

    - + @@ -1146,7 +1143,7 @@ - + @@ -1155,16 +1152,13 @@ - - - -
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
     No newer versions available.
    Group Id org.apache.maven
    maven-core
    Current Version3.3.3
    3.3.9
    Scope
    Typejar
    Newer versions3.3.9 Next Incremental
    +jar

    org.apache.maven:maven-plugin-api

    - + @@ -1173,7 +1167,7 @@ - + @@ -1182,16 +1176,13 @@ - - - -
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
     No newer versions available.
    Group Id org.apache.maven
    maven-plugin-api
    Current Version3.3.3
    3.3.9
    Scope
    Typejar
    Newer versions3.3.9 Next Incremental
    +jar

    org.apache.maven:maven-settings

    - + @@ -1200,7 +1191,7 @@ - + @@ -1209,10 +1200,7 @@ - - - -
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
     No newer versions available.
    Group Id org.apache.maven
    maven-settings
    Current Version3.3.3
    3.3.9
    Scope
    Typejar
    Newer versions3.3.9 Next Incremental
    +jar

    org.apache.maven.plugin-testing:maven-plugin-testing-harness

    @@ -1362,7 +1350,7 @@
    - + @@ -1380,13 +1368,16 @@ -
    Status No newer versions available.
     There is at least one newer minor version available. Minor updates are sometimes passive.
    Group Id org.jmockit
    Typejar
    +jar + +Newer versions +1.23 Next Minor
    1.24 Latest Minor

    org.jsoup:jsoup

    - + @@ -1395,7 +1386,7 @@ - + @@ -1404,7 +1395,10 @@ -
    Status No newer versions available.
     There is at least one newer incremental version available. Incremental updates are typically passive.
    Group Id org.jsoup
    jsoup
    Current Version1.8.3
    1.9.1
    Scope
    Typejar
    +jar + +Newer versions +1.9.2 Next Incremental

    org.owasp:dependency-check-core

    @@ -1419,7 +1413,7 @@ - + @@ -1443,7 +1437,7 @@ - + diff --git a/dependency-check-ant/findbugs.html b/dependency-check-ant/findbugs.html index 7b7545826..62f02f09e 100644 --- a/dependency-check-ant/findbugs.html +++ b/dependency-check-ant/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-ant – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ @@ -215,9 +215,6 @@ developed using - - - built on cloudbees @@ -267,7 +264,7 @@ - +
    dependency-check-core
    Current Version1.3.6
    1.4.0
    Scope compile
    dependency-check-utils
    Current Version1.3.6
    1.4.0
    Scope compile
    Inconsistent synchronization of org.owasp.dependencycheck.taskdefs.Check.path; locked 44% of time MT_CORRECTNESS IS2_INCONSISTENT_SYNC838870 Medium
    diff --git a/dependency-check-ant/index.html b/dependency-check-ant/index.html index bfa37045e..70d962843 100644 --- a/dependency-check-ant/index.html +++ b/dependency-check-ant/index.html @@ -1,13 +1,13 @@ - + dependency-check-ant – About @@ -52,7 +52,7 @@ @@ -136,9 +136,6 @@ developed using - - - built on cloudbees @@ -153,7 +150,7 @@
      -
    1. Download dependency-check-ant from bintray here.
    2. +
    3. Download dependency-check-ant from bintray here.
    4. Unzip the archive
    5. @@ -165,8 +162,11 @@ <property name="dependency-check.home" value="C:/tools/dependency-check-ant"/> <path id="dependency-check.path"> <pathelement location="${dependency-check.home}/dependency-check-ant.jar"/> + <fileset dir="${dependency-check.home}/lib"> + <include name="*.jar"/> + </fileset> </path> - <taskdef resource="dependency-check-taskdefs.properties"> +<taskdef resource="dependency-check-taskdefs.properties"> <classpath refid="dependency-check.path" /> </taskdef> diff --git a/dependency-check-ant/integration.html b/dependency-check-ant/integration.html index bcc02fc93..76e088e8a 100644 --- a/dependency-check-ant/integration.html +++ b/dependency-check-ant/integration.html @@ -1,13 +1,13 @@ - + dependency-check-ant – CI Management @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees @@ -200,11 +197,11 @@

      Overview

      -

      This project uses Continuous Integration System.

      +

      This project uses Travis CI.

      Access

      The following is a link to the continuous integration system used by the project:

      -
      +
      https://travis-ci.org/jeremylong/DependencyCheck

      Notifiers

      No notifiers are defined. Please check back at a later date.

      diff --git a/dependency-check-ant/issue-tracking.html b/dependency-check-ant/issue-tracking.html index bd01a77bf..378db0cc3 100644 --- a/dependency-check-ant/issue-tracking.html +++ b/dependency-check-ant/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Issue Management @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/license.html b/dependency-check-ant/license.html index eb42d8fa3..4c298a65d 100644 --- a/dependency-check-ant/license.html +++ b/dependency-check-ant/license.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Licenses @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/mail-lists.html b/dependency-check-ant/mail-lists.html index 9667f4f5f..ce7c4c66f 100644 --- a/dependency-check-ant/mail-lists.html +++ b/dependency-check-ant/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Mailing Lists @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/plugin-updates-report.html b/dependency-check-ant/plugin-updates-report.html index 21a1d389d..c41d3ed4c 100644 --- a/dependency-check-ant/plugin-updates-report.html +++ b/dependency-check-ant/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Plugin Updates Report @@ -52,7 +52,7 @@ @@ -215,9 +215,6 @@ developed using - - - built on cloudbees @@ -233,7 +230,7 @@ # of plugins using the latest version available -19 +18 # of plugins where the next version available is smaller than an incremental version update @@ -249,7 +246,7 @@ # of plugins where the next version available is a major version update -0 +1 # of plugins where a dependencies section containes a dependency with an updated version @@ -371,7 +368,7 @@ org.apache.maven.plugins maven-jar-plugin -2.6 +3.0.0 @@ -401,7 +398,7 @@ org.apache.maven.plugins maven-resources-plugin -2.7 +3.0.0 @@ -411,21 +408,21 @@ org.apache.maven.plugins maven-site-plugin -3.5 +3.5.1 - + org.apache.maven.plugins maven-source-plugin -2.4 - +2.4 +3.0.0 @@ -637,7 +634,7 @@ maven-jar-plugin Current Version -2.6 +3.0.0

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -682,7 +679,7 @@ -
      maven-resources-plugin
      Current Version2.7
      +3.0.0

      Plugin org.apache.maven.plugins:maven-site-plugin

      @@ -697,13 +694,13 @@ -
      maven-site-plugin
      Current Version3.5
      +3.5.1

      Plugin org.apache.maven.plugins:maven-source-plugin

      - + @@ -712,7 +709,10 @@ -
      Status No newer versions available.
       There is at least one newer major version available. Major updates are rarely passive.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      +2.4 + +Newer versions +3.0.0 Next Major

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-ant/project-info.html b/dependency-check-ant/project-info.html index 0cfce4146..183cda180 100644 --- a/dependency-check-ant/project-info.html +++ b/dependency-check-ant/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Information @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/project-reports.html b/dependency-check-ant/project-reports.html index b4575e012..d2a0f70fc 100644 --- a/dependency-check-ant/project-reports.html +++ b/dependency-check-ant/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Generated Reports @@ -52,7 +52,7 @@ @@ -215,9 +215,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/project-summary.html b/dependency-check-ant/project-summary.html index b4282dd6f..cfbe4f71c 100644 --- a/dependency-check-ant/project-summary.html +++ b/dependency-check-ant/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Summary @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees @@ -241,7 +238,7 @@ - + diff --git a/dependency-check-ant/source-repository.html b/dependency-check-ant/source-repository.html index 9b6ed3b5f..8ac1dcba0 100644 --- a/dependency-check-ant/source-repository.html +++ b/dependency-check-ant/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Source Code Management @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/surefire-report.html b/dependency-check-ant/surefire-report.html index abb6db89a..d54168ed6 100644 --- a/dependency-check-ant/surefire-report.html +++ b/dependency-check-ant/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Surefire Report @@ -52,7 +52,7 @@ @@ -215,9 +215,6 @@ developed using - - - built on cloudbees @@ -262,7 +259,7 @@ function toggleDisplay(elementId) { -
      dependency-check-ant
      Version1.3.6
      1.4.0
      Type jar
      0 0 100%18.409

      +16.843

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -283,7 +280,7 @@ function toggleDisplay(elementId) { 0 0 100% -18.409
      +16.843

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.taskdefs

      @@ -305,7 +302,7 @@ function toggleDisplay(elementId) { 0 0 100% -18.409

      +16.843

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -315,19 +312,19 @@ function toggleDisplay(elementId) { testGetFailBuildOnCVSS -0.67 +0.402 testAddDirSet -8.209 +7.583 testAddFileSet -5.416 +4.888 testAddFileList -3.989

      +3.884
      diff --git a/dependency-check-ant/taglist.html b/dependency-check-ant/taglist.html index f2850e0d0..f81456efa 100644 --- a/dependency-check-ant/taglist.html +++ b/dependency-check-ant/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Tag List report @@ -52,7 +52,7 @@ @@ -215,9 +215,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/team-list.html b/dependency-check-ant/team-list.html index 283691c53..38b0559b4 100644 --- a/dependency-check-ant/team-list.html +++ b/dependency-check-ant/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Team @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-ant/xref-test/index.html b/dependency-check-ant/xref-test/index.html index 22912bedb..87b737854 100644 --- a/dependency-check-ant/xref-test/index.html +++ b/dependency-check-ant/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Ant Task 1.3.6 Reference + Dependency-Check Ant Task 1.4.0 Reference diff --git a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html index c0f72544b..106e7d141 100644 --- a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html +++ b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html index 9b5ccd6f1..e0c2c2c73 100644 --- a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/dependency-check-ant/xref-test/overview-frame.html b/dependency-check-ant/xref-test/overview-frame.html index 6c48cdd09..815bfa189 100644 --- a/dependency-check-ant/xref-test/overview-frame.html +++ b/dependency-check-ant/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference + Dependency-Check Ant Task 1.4.0 Reference diff --git a/dependency-check-ant/xref-test/overview-summary.html b/dependency-check-ant/xref-test/overview-summary.html index b0e51e6e5..9be5448cb 100644 --- a/dependency-check-ant/xref-test/overview-summary.html +++ b/dependency-check-ant/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference + Dependency-Check Ant Task 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Ant Task 1.3.6 Reference

      +

      Dependency-Check Ant Task 1.4.0 Reference

      diff --git a/dependency-check-ant/xref/index.html b/dependency-check-ant/xref/index.html index 22912bedb..87b737854 100644 --- a/dependency-check-ant/xref/index.html +++ b/dependency-check-ant/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Ant Task 1.3.6 Reference + Dependency-Check Ant Task 1.4.0 Reference diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html index c157c645f..f96519771 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference Package org.owasp.dependencycheck.ant.logging + Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.ant.logging diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html index de31df2d0..b47da75a0 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference Package org.owasp.dependencycheck.ant.logging + Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.ant.logging diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Check.html b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Check.html index 08ce2d77b..2c447834d 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Check.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Check.html @@ -94,8 +94,8 @@ 86 } 8788/** -89 * Returns the path. If the path has not been initialized yet, this class is synchronized, and will instantiate the path -90 * object. +89 * Returns the path. If the path has not been initialized yet, this class is +90 * synchronized, and will instantiate the path object.91 *92 * @return the path93 */ @@ -117,861 +117,898 @@ 109 } 110111/** -112 * Add a reference to a Path, FileSet, DirSet, or FileList defined elsewhere. -113 * -114 * @param r the reference to a path, fileset, dirset or filelist. -115 */ -116publicvoid setRefid(Reference r) { -117if (path != null) { -118thrownew BuildException("Nested elements are not allowed when using the refid attribute."); -119 } -120 refid = r; -121 } -122 -123/** -124 * If this is a reference, this method will add the referenced resource collection to the collection of paths. -125 * -126 * @throws BuildException if the reference is not to a resource collection -127 */ -128privatevoid dealWithReferences() throws BuildException { -129if (isReference()) { -130final Object o = refid.getReferencedObject(getProject()); -131if (!(o instanceof ResourceCollection)) { -132thrownew BuildException("refid '" + refid.getRefId() -133 + "' does not refer to a resource collection."); -134 } -135 getPath().add((ResourceCollection) o); -136 } -137 } -138// END COPY from org.apache.tools.ant.taskdefs -139/** -140 * The application name for the report. -141 * -142 * @deprecated use projectName instead. -143 */ -144 @Deprecated -145private String applicationName = null; -146 -147/** -148 * Get the value of applicationName. -149 * -150 * @return the value of applicationName +112 * Add a reference to a Path, FileSet, DirSet, or FileList defined +113 * elsewhere. +114 * +115 * @param r the reference to a path, fileset, dirset or filelist. +116 */ +117publicvoid setRefid(Reference r) { +118if (path != null) { +119thrownew BuildException("Nested elements are not allowed when using the refid attribute."); +120 } +121 refid = r; +122 } +123 +124/** +125 * If this is a reference, this method will add the referenced resource +126 * collection to the collection of paths. +127 * +128 * @throws BuildException if the reference is not to a resource collection +129 */ +130privatevoid dealWithReferences() throws BuildException { +131if (isReference()) { +132final Object o = refid.getReferencedObject(getProject()); +133if (!(o instanceof ResourceCollection)) { +134thrownew BuildException("refid '" + refid.getRefId() +135 + "' does not refer to a resource collection."); +136 } +137 getPath().add((ResourceCollection) o); +138 } +139 } +140// END COPY from org.apache.tools.ant.taskdefs +141/** +142 * The application name for the report. +143 * +144 * @deprecated use projectName instead. +145 */ +146 @Deprecated +147private String applicationName = null; +148 +149/** +150 * Get the value of applicationName.151 * -152 * @deprecated use projectName instead. -153 */ -154 @Deprecated -155public String getApplicationName() { -156return applicationName; -157 } -158 -159/** -160 * Set the value of applicationName. -161 * -162 * @param applicationName new value of applicationName -163 * @deprecated use projectName instead. -164 */ -165 @Deprecated -166publicvoid setApplicationName(String applicationName) { -167this.applicationName = applicationName; -168 } -169/** -170 * The name of the project being analyzed. -171 */ -172private String projectName = "dependency-check"; -173 -174/** -175 * Get the value of projectName. -176 * -177 * @return the value of projectName -178 */ -179public String getProjectName() { -180if (applicationName != null) { -181 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN); -182if ("dependency-check".equals(projectName)) { -183 projectName = applicationName; -184 } -185 } -186return projectName; -187 } -188 -189/** -190 * Set the value of projectName. -191 * -192 * @param projectName new value of projectName -193 */ -194publicvoid setProjectName(String projectName) { -195this.projectName = projectName; -196 } -197 -198/** -199 * Specifies the destination directory for the generated Dependency-Check report. -200 */ -201private String reportOutputDirectory = "."; -202 -203/** -204 * Get the value of reportOutputDirectory. -205 * -206 * @return the value of reportOutputDirectory -207 */ -208public String getReportOutputDirectory() { -209return reportOutputDirectory; -210 } -211 -212/** -213 * Set the value of reportOutputDirectory. -214 * -215 * @param reportOutputDirectory new value of reportOutputDirectory -216 */ -217publicvoid setReportOutputDirectory(String reportOutputDirectory) { -218this.reportOutputDirectory = reportOutputDirectory; -219 } -220/** -221 * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which -222 * means since the CVSS scores are 0-10, by default the build will never fail and the CVSS score is set to 11. The valid range -223 * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail. -224 */ -225privatefloat failBuildOnCVSS = 11; -226 -227/** -228 * Get the value of failBuildOnCVSS. -229 * -230 * @return the value of failBuildOnCVSS -231 */ -232publicfloat getFailBuildOnCVSS() { -233return failBuildOnCVSS; -234 } -235 -236/** -237 * Set the value of failBuildOnCVSS. -238 * -239 * @param failBuildOnCVSS new value of failBuildOnCVSS -240 */ -241publicvoid setFailBuildOnCVSS(float failBuildOnCVSS) { -242this.failBuildOnCVSS = failBuildOnCVSS; -243 } -244/** -245 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default -246 * is true. -247 */ -248private Boolean autoUpdate; -249 -250/** -251 * Get the value of autoUpdate. -252 * -253 * @return the value of autoUpdate -254 */ -255public Boolean isAutoUpdate() { -256return autoUpdate; -257 } -258 -259/** -260 * Set the value of autoUpdate. -261 * -262 * @param autoUpdate new value of autoUpdate -263 */ -264publicvoid setAutoUpdate(Boolean autoUpdate) { -265this.autoUpdate = autoUpdate; -266 } -267/** -268 * Whether only the update phase should be executed. -269 * -270 * @deprecated Use the update task instead -271 */ -272 @Deprecated -273privateboolean updateOnly = false; -274 -275/** -276 * Get the value of updateOnly. -277 * -278 * @return the value of updateOnly -279 * @deprecated Use the update task instead -280 */ -281 @Deprecated -282publicboolean isUpdateOnly() { -283return updateOnly; -284 } -285 -286/** -287 * Set the value of updateOnly. -288 * -289 * @param updateOnly new value of updateOnly -290 * @deprecated Use the update task instead -291 */ -292 @Deprecated -293publicvoid setUpdateOnly(boolean updateOnly) { -294this.updateOnly = updateOnly; -295 } -296 -297/** -298 * The report format to be generated (HTML, XML, VULN, ALL). Default is HTML. -299 */ -300private String reportFormat = "HTML"; +152 * @return the value of applicationName +153 * +154 * @deprecated use projectName instead. +155 */ +156 @Deprecated +157public String getApplicationName() { +158return applicationName; +159 } +160 +161/** +162 * Set the value of applicationName. +163 * +164 * @param applicationName new value of applicationName +165 * @deprecated use projectName instead. +166 */ +167 @Deprecated +168publicvoid setApplicationName(String applicationName) { +169this.applicationName = applicationName; +170 } +171/** +172 * The name of the project being analyzed. +173 */ +174private String projectName = "dependency-check"; +175 +176/** +177 * Get the value of projectName. +178 * +179 * @return the value of projectName +180 */ +181public String getProjectName() { +182if (applicationName != null) { +183 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN); +184if ("dependency-check".equals(projectName)) { +185 projectName = applicationName; +186 } +187 } +188return projectName; +189 } +190 +191/** +192 * Set the value of projectName. +193 * +194 * @param projectName new value of projectName +195 */ +196publicvoid setProjectName(String projectName) { +197this.projectName = projectName; +198 } +199 +200/** +201 * Specifies the destination directory for the generated Dependency-Check +202 * report. +203 */ +204private String reportOutputDirectory = "."; +205 +206/** +207 * Get the value of reportOutputDirectory. +208 * +209 * @return the value of reportOutputDirectory +210 */ +211public String getReportOutputDirectory() { +212return reportOutputDirectory; +213 } +214 +215/** +216 * Set the value of reportOutputDirectory. +217 * +218 * @param reportOutputDirectory new value of reportOutputDirectory +219 */ +220publicvoid setReportOutputDirectory(String reportOutputDirectory) { +221this.reportOutputDirectory = reportOutputDirectory; +222 } +223/** +224 * Specifies if the build should be failed if a CVSS score above a specified +225 * level is identified. The default is 11 which means since the CVSS scores +226 * are 0-10, by default the build will never fail and the CVSS score is set +227 * to 11. The valid range for the fail build on CVSS is 0 to 11, where +228 * anything above 10 will not cause the build to fail. +229 */ +230privatefloat failBuildOnCVSS = 11; +231 +232/** +233 * Get the value of failBuildOnCVSS. +234 * +235 * @return the value of failBuildOnCVSS +236 */ +237publicfloat getFailBuildOnCVSS() { +238return failBuildOnCVSS; +239 } +240 +241/** +242 * Set the value of failBuildOnCVSS. +243 * +244 * @param failBuildOnCVSS new value of failBuildOnCVSS +245 */ +246publicvoid setFailBuildOnCVSS(float failBuildOnCVSS) { +247this.failBuildOnCVSS = failBuildOnCVSS; +248 } +249/** +250 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +251 * recommended that this be turned to false. Default is true. +252 */ +253private Boolean autoUpdate; +254 +255/** +256 * Get the value of autoUpdate. +257 * +258 * @return the value of autoUpdate +259 */ +260public Boolean isAutoUpdate() { +261return autoUpdate; +262 } +263 +264/** +265 * Set the value of autoUpdate. +266 * +267 * @param autoUpdate new value of autoUpdate +268 */ +269publicvoid setAutoUpdate(Boolean autoUpdate) { +270this.autoUpdate = autoUpdate; +271 } +272/** +273 * Whether only the update phase should be executed. +274 * +275 * @deprecated Use the update task instead +276 */ +277 @Deprecated +278privateboolean updateOnly = false; +279 +280/** +281 * Get the value of updateOnly. +282 * +283 * @return the value of updateOnly +284 * @deprecated Use the update task instead +285 */ +286 @Deprecated +287publicboolean isUpdateOnly() { +288return updateOnly; +289 } +290 +291/** +292 * Set the value of updateOnly. +293 * +294 * @param updateOnly new value of updateOnly +295 * @deprecated Use the update task instead +296 */ +297 @Deprecated +298publicvoid setUpdateOnly(boolean updateOnly) { +299this.updateOnly = updateOnly; +300 } 301302/** -303 * Get the value of reportFormat. -304 * -305 * @return the value of reportFormat -306 */ -307public String getReportFormat() { -308return reportFormat; -309 } -310 -311/** -312 * Set the value of reportFormat. -313 * -314 * @param reportFormat new value of reportFormat -315 */ -316publicvoid setReportFormat(ReportFormats reportFormat) { -317this.reportFormat = reportFormat.getValue(); -318 } -319/** -320 * The path to the suppression file. +303 * The report format to be generated (HTML, XML, VULN, ALL). Default is +304 * HTML. +305 */ +306private String reportFormat = "HTML"; +307 +308/** +309 * Get the value of reportFormat. +310 * +311 * @return the value of reportFormat +312 */ +313public String getReportFormat() { +314return reportFormat; +315 } +316 +317/** +318 * Set the value of reportFormat. +319 * +320 * @param reportFormat new value of reportFormat321 */ -322private String suppressionFile; -323 -324/** -325 * Get the value of suppressionFile. -326 * -327 * @return the value of suppressionFile -328 */ -329public String getSuppressionFile() { -330return suppressionFile; -331 } -332 -333/** -334 * Set the value of suppressionFile. -335 * -336 * @param suppressionFile new value of suppressionFile -337 */ -338publicvoid setSuppressionFile(String suppressionFile) { -339this.suppressionFile = suppressionFile; -340 } -341/** -342 * flag indicating whether or not to show a summary of findings. +322publicvoid setReportFormat(ReportFormats reportFormat) { +323this.reportFormat = reportFormat.getValue(); +324 } +325/** +326 * The path to the suppression file. +327 */ +328private String suppressionFile; +329 +330/** +331 * Get the value of suppressionFile. +332 * +333 * @return the value of suppressionFile +334 */ +335public String getSuppressionFile() { +336return suppressionFile; +337 } +338 +339/** +340 * Set the value of suppressionFile. +341 * +342 * @param suppressionFile new value of suppressionFile343 */ -344privateboolean showSummary = true; -345 -346/** -347 * Get the value of showSummary. -348 * -349 * @return the value of showSummary -350 */ -351publicboolean isShowSummary() { -352return showSummary; -353 } -354 -355/** -356 * Set the value of showSummary. -357 * -358 * @param showSummary new value of showSummary -359 */ -360publicvoid setShowSummary(boolean showSummary) { -361this.showSummary = showSummary; -362 } -363 -364/** -365 * Whether or not the Jar Analyzer is enabled. -366 */ -367private Boolean jarAnalyzerEnabled; -368 -369/** -370 * Returns whether or not the analyzer is enabled. -371 * -372 * @return true if the analyzer is enabled -373 */ -374public Boolean isJarAnalyzerEnabled() { -375return jarAnalyzerEnabled; -376 } -377 -378/** -379 * Sets whether or not the analyzer is enabled. -380 * -381 * @param jarAnalyzerEnabled the value of the new setting -382 */ -383publicvoid setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) { -384this.jarAnalyzerEnabled = jarAnalyzerEnabled; -385 } -386/** -387 * Whether or not the Archive Analyzer is enabled. +344publicvoid setSuppressionFile(String suppressionFile) { +345this.suppressionFile = suppressionFile; +346 } +347/** +348 * flag indicating whether or not to show a summary of findings. +349 */ +350privateboolean showSummary = true; +351 +352/** +353 * Get the value of showSummary. +354 * +355 * @return the value of showSummary +356 */ +357publicboolean isShowSummary() { +358return showSummary; +359 } +360 +361/** +362 * Set the value of showSummary. +363 * +364 * @param showSummary new value of showSummary +365 */ +366publicvoid setShowSummary(boolean showSummary) { +367this.showSummary = showSummary; +368 } +369 +370/** +371 * Whether experimental analyzers are enabled. +372 */ +373private Boolean enableExperimental; +374 +375/** +376 * Get the value of enableExperimental. +377 * +378 * @return the value of enableExperimental +379 */ +380public Boolean isEnableExperimental() { +381return enableExperimental; +382 } +383 +384/** +385 * Set the value of enableExperimental. +386 * +387 * @param enableExperimental new value of enableExperimental388 */ -389private Boolean archiveAnalyzerEnabled; -390 -391/** -392 * Returns whether or not the analyzer is enabled. -393 * -394 * @return true if the analyzer is enabled +389publicvoid setEnableExperimental(Boolean enableExperimental) { +390this.enableExperimental = enableExperimental; +391 } +392 +393/** +394 * Whether or not the Jar Analyzer is enabled.395 */ -396public Boolean isArchiveAnalyzerEnabled() { -397return archiveAnalyzerEnabled; -398 } -399/** -400 * Whether or not the .NET Assembly Analyzer is enabled. -401 */ -402private Boolean assemblyAnalyzerEnabled; -403 -404/** -405 * Sets whether or not the analyzer is enabled. -406 * -407 * @param archiveAnalyzerEnabled the value of the new setting -408 */ -409publicvoid setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) { -410this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; -411 } -412 -413/** -414 * Returns whether or not the analyzer is enabled. -415 * -416 * @return true if the analyzer is enabled +396private Boolean jarAnalyzerEnabled; +397 +398/** +399 * Returns whether or not the analyzer is enabled. +400 * +401 * @return true if the analyzer is enabled +402 */ +403public Boolean isJarAnalyzerEnabled() { +404return jarAnalyzerEnabled; +405 } +406 +407/** +408 * Sets whether or not the analyzer is enabled. +409 * +410 * @param jarAnalyzerEnabled the value of the new setting +411 */ +412publicvoid setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) { +413this.jarAnalyzerEnabled = jarAnalyzerEnabled; +414 } +415/** +416 * Whether or not the Archive Analyzer is enabled.417 */ -418public Boolean isAssemblyAnalyzerEnabled() { -419return assemblyAnalyzerEnabled; -420 } -421 -422/** -423 * Sets whether or not the analyzer is enabled. -424 * -425 * @param assemblyAnalyzerEnabled the value of the new setting -426 */ -427publicvoid setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) { -428this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; -429 } -430/** -431 * Whether or not the .NET Nuspec Analyzer is enabled. -432 */ -433private Boolean nuspecAnalyzerEnabled; -434 -435/** -436 * Returns whether or not the analyzer is enabled. -437 * -438 * @return true if the analyzer is enabled -439 */ -440public Boolean isNuspecAnalyzerEnabled() { -441return nuspecAnalyzerEnabled; -442 } -443 -444/** -445 * Sets whether or not the analyzer is enabled. -446 * -447 * @param nuspecAnalyzerEnabled the value of the new setting -448 */ -449publicvoid setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) { -450this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; -451 } -452/** -453 * Whether or not the PHP Composer Analyzer is enabled. -454 */ -455private Boolean composerAnalyzerEnabled; -456 -457/** -458 * Get the value of composerAnalyzerEnabled. -459 * -460 * @return the value of composerAnalyzerEnabled +418private Boolean archiveAnalyzerEnabled; +419 +420/** +421 * Returns whether or not the analyzer is enabled. +422 * +423 * @return true if the analyzer is enabled +424 */ +425public Boolean isArchiveAnalyzerEnabled() { +426return archiveAnalyzerEnabled; +427 } +428/** +429 * Whether or not the .NET Assembly Analyzer is enabled. +430 */ +431private Boolean assemblyAnalyzerEnabled; +432 +433/** +434 * Sets whether or not the analyzer is enabled. +435 * +436 * @param archiveAnalyzerEnabled the value of the new setting +437 */ +438publicvoid setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) { +439this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; +440 } +441 +442/** +443 * Returns whether or not the analyzer is enabled. +444 * +445 * @return true if the analyzer is enabled +446 */ +447public Boolean isAssemblyAnalyzerEnabled() { +448return assemblyAnalyzerEnabled; +449 } +450 +451/** +452 * Sets whether or not the analyzer is enabled. +453 * +454 * @param assemblyAnalyzerEnabled the value of the new setting +455 */ +456publicvoid setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) { +457this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; +458 } +459/** +460 * Whether or not the .NET Nuspec Analyzer is enabled.461 */ -462public Boolean isComposerAnalyzerEnabled() { -463return composerAnalyzerEnabled; -464 } -465 -466/** -467 * Set the value of composerAnalyzerEnabled. -468 * -469 * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled -470 */ -471publicvoid setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) { -472this.composerAnalyzerEnabled = composerAnalyzerEnabled; -473 } -474/** -475 * Whether the autoconf analyzer should be enabled. -476 */ -477private Boolean autoconfAnalyzerEnabled; -478 -479/** -480 * Get the value of autoconfAnalyzerEnabled. -481 * -482 * @return the value of autoconfAnalyzerEnabled +462private Boolean nuspecAnalyzerEnabled; +463 +464/** +465 * Returns whether or not the analyzer is enabled. +466 * +467 * @return true if the analyzer is enabled +468 */ +469public Boolean isNuspecAnalyzerEnabled() { +470return nuspecAnalyzerEnabled; +471 } +472 +473/** +474 * Sets whether or not the analyzer is enabled. +475 * +476 * @param nuspecAnalyzerEnabled the value of the new setting +477 */ +478publicvoid setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) { +479this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; +480 } +481/** +482 * Whether or not the PHP Composer Analyzer is enabled.483 */ -484public Boolean isAutoconfAnalyzerEnabled() { -485return autoconfAnalyzerEnabled; -486 } -487 -488/** -489 * Set the value of autoconfAnalyzerEnabled. -490 * -491 * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled -492 */ -493publicvoid setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) { -494this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled; -495 } -496/** -497 * Whether the CMake analyzer should be enabled. -498 */ -499private Boolean cmakeAnalyzerEnabled; -500 -501/** -502 * Get the value of cmakeAnalyzerEnabled. -503 * -504 * @return the value of cmakeAnalyzerEnabled +484private Boolean composerAnalyzerEnabled; +485 +486/** +487 * Get the value of composerAnalyzerEnabled. +488 * +489 * @return the value of composerAnalyzerEnabled +490 */ +491public Boolean isComposerAnalyzerEnabled() { +492return composerAnalyzerEnabled; +493 } +494 +495/** +496 * Set the value of composerAnalyzerEnabled. +497 * +498 * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled +499 */ +500publicvoid setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) { +501this.composerAnalyzerEnabled = composerAnalyzerEnabled; +502 } +503/** +504 * Whether the autoconf analyzer should be enabled.505 */ -506public Boolean isCMakeAnalyzerEnabled() { -507return cmakeAnalyzerEnabled; -508 } -509 -510/** -511 * Set the value of cmakeAnalyzerEnabled. -512 * -513 * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled -514 */ -515publicvoid setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) { -516this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled; -517 } -518/** -519 * Whether or not the openssl analyzer is enabled. -520 */ -521private Boolean opensslAnalyzerEnabled; -522 -523/** -524 * Get the value of opensslAnalyzerEnabled. -525 * -526 * @return the value of opensslAnalyzerEnabled +506private Boolean autoconfAnalyzerEnabled; +507 +508/** +509 * Get the value of autoconfAnalyzerEnabled. +510 * +511 * @return the value of autoconfAnalyzerEnabled +512 */ +513public Boolean isAutoconfAnalyzerEnabled() { +514return autoconfAnalyzerEnabled; +515 } +516 +517/** +518 * Set the value of autoconfAnalyzerEnabled. +519 * +520 * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled +521 */ +522publicvoid setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) { +523this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled; +524 } +525/** +526 * Whether the CMake analyzer should be enabled.527 */ -528public Boolean isOpensslAnalyzerEnabled() { -529return opensslAnalyzerEnabled; -530 } -531 -532/** -533 * Set the value of opensslAnalyzerEnabled. -534 * -535 * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled -536 */ -537publicvoid setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) { -538this.opensslAnalyzerEnabled = opensslAnalyzerEnabled; -539 } -540/** -541 * Whether or not the Node.js Analyzer is enabled. -542 */ -543private Boolean nodeAnalyzerEnabled; -544 -545/** -546 * Get the value of nodeAnalyzerEnabled. -547 * -548 * @return the value of nodeAnalyzerEnabled +528private Boolean cmakeAnalyzerEnabled; +529 +530/** +531 * Get the value of cmakeAnalyzerEnabled. +532 * +533 * @return the value of cmakeAnalyzerEnabled +534 */ +535public Boolean isCMakeAnalyzerEnabled() { +536return cmakeAnalyzerEnabled; +537 } +538 +539/** +540 * Set the value of cmakeAnalyzerEnabled. +541 * +542 * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled +543 */ +544publicvoid setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) { +545this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled; +546 } +547/** +548 * Whether or not the openssl analyzer is enabled.549 */ -550public Boolean isNodeAnalyzerEnabled() { -551return nodeAnalyzerEnabled; -552 } -553 -554/** -555 * Set the value of nodeAnalyzerEnabled. -556 * -557 * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled -558 */ -559publicvoid setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) { -560this.nodeAnalyzerEnabled = nodeAnalyzerEnabled; -561 } -562/** -563 * Whether the ruby gemspec analyzer should be enabled. -564 */ -565private Boolean rubygemsAnalyzerEnabled; -566 -567/** -568 * Get the value of rubygemsAnalyzerEnabled. -569 * -570 * @return the value of rubygemsAnalyzerEnabled +550private Boolean opensslAnalyzerEnabled; +551 +552/** +553 * Get the value of opensslAnalyzerEnabled. +554 * +555 * @return the value of opensslAnalyzerEnabled +556 */ +557public Boolean isOpensslAnalyzerEnabled() { +558return opensslAnalyzerEnabled; +559 } +560 +561/** +562 * Set the value of opensslAnalyzerEnabled. +563 * +564 * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled +565 */ +566publicvoid setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) { +567this.opensslAnalyzerEnabled = opensslAnalyzerEnabled; +568 } +569/** +570 * Whether or not the Node.js Analyzer is enabled.571 */ -572public Boolean isRubygemsAnalyzerEnabled() { -573return rubygemsAnalyzerEnabled; -574 } -575 -576/** -577 * Set the value of rubygemsAnalyzerEnabled. -578 * -579 * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled -580 */ -581publicvoid setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) { -582this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled; -583 } -584/** -585 * Whether the python package analyzer should be enabled. -586 */ -587private Boolean pyPackageAnalyzerEnabled; -588 -589/** -590 * Get the value of pyPackageAnalyzerEnabled. -591 * -592 * @return the value of pyPackageAnalyzerEnabled +572private Boolean nodeAnalyzerEnabled; +573 +574/** +575 * Get the value of nodeAnalyzerEnabled. +576 * +577 * @return the value of nodeAnalyzerEnabled +578 */ +579public Boolean isNodeAnalyzerEnabled() { +580return nodeAnalyzerEnabled; +581 } +582 +583/** +584 * Set the value of nodeAnalyzerEnabled. +585 * +586 * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled +587 */ +588publicvoid setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) { +589this.nodeAnalyzerEnabled = nodeAnalyzerEnabled; +590 } +591/** +592 * Whether the ruby gemspec analyzer should be enabled.593 */ -594public Boolean isPyPackageAnalyzerEnabled() { -595return pyPackageAnalyzerEnabled; -596 } -597 -598/** -599 * Set the value of pyPackageAnalyzerEnabled. -600 * -601 * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled -602 */ -603publicvoid setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) { -604this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled; -605 } -606 -607/** -608 * Whether the python distribution analyzer should be enabled. +594private Boolean rubygemsAnalyzerEnabled; +595 +596/** +597 * Get the value of rubygemsAnalyzerEnabled. +598 * +599 * @return the value of rubygemsAnalyzerEnabled +600 */ +601public Boolean isRubygemsAnalyzerEnabled() { +602return rubygemsAnalyzerEnabled; +603 } +604 +605/** +606 * Set the value of rubygemsAnalyzerEnabled. +607 * +608 * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled609 */ -610private Boolean pyDistributionAnalyzerEnabled; -611 -612/** -613 * Get the value of pyDistributionAnalyzerEnabled. -614 * -615 * @return the value of pyDistributionAnalyzerEnabled -616 */ -617public Boolean isPyDistributionAnalyzerEnabled() { -618return pyDistributionAnalyzerEnabled; -619 } -620 -621/** -622 * Set the value of pyDistributionAnalyzerEnabled. -623 * -624 * @param pyDistributionAnalyzerEnabled new value of pyDistributionAnalyzerEnabled -625 */ -626publicvoid setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { -627this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; -628 } -629 -630/** -631 * Whether or not the central analyzer is enabled. -632 */ -633private Boolean centralAnalyzerEnabled; -634 -635/** -636 * Get the value of centralAnalyzerEnabled. -637 * -638 * @return the value of centralAnalyzerEnabled -639 */ -640public Boolean isCentralAnalyzerEnabled() { -641return centralAnalyzerEnabled; -642 } -643 -644/** -645 * Set the value of centralAnalyzerEnabled. -646 * -647 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled -648 */ -649publicvoid setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) { -650this.centralAnalyzerEnabled = centralAnalyzerEnabled; -651 } -652 -653/** -654 * Whether or not the nexus analyzer is enabled. +610publicvoid setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) { +611this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled; +612 } +613/** +614 * Whether the python package analyzer should be enabled. +615 */ +616private Boolean pyPackageAnalyzerEnabled; +617 +618/** +619 * Get the value of pyPackageAnalyzerEnabled. +620 * +621 * @return the value of pyPackageAnalyzerEnabled +622 */ +623public Boolean isPyPackageAnalyzerEnabled() { +624return pyPackageAnalyzerEnabled; +625 } +626 +627/** +628 * Set the value of pyPackageAnalyzerEnabled. +629 * +630 * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled +631 */ +632publicvoid setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) { +633this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled; +634 } +635 +636/** +637 * Whether the python distribution analyzer should be enabled. +638 */ +639private Boolean pyDistributionAnalyzerEnabled; +640 +641/** +642 * Get the value of pyDistributionAnalyzerEnabled. +643 * +644 * @return the value of pyDistributionAnalyzerEnabled +645 */ +646public Boolean isPyDistributionAnalyzerEnabled() { +647return pyDistributionAnalyzerEnabled; +648 } +649 +650/** +651 * Set the value of pyDistributionAnalyzerEnabled. +652 * +653 * @param pyDistributionAnalyzerEnabled new value of +654 * pyDistributionAnalyzerEnabled655 */ -656private Boolean nexusAnalyzerEnabled; -657 -658/** -659 * Get the value of nexusAnalyzerEnabled. -660 * -661 * @return the value of nexusAnalyzerEnabled +656publicvoid setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { +657this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; +658 } +659 +660/** +661 * Whether or not the central analyzer is enabled.662 */ -663public Boolean isNexusAnalyzerEnabled() { -664return nexusAnalyzerEnabled; -665 } -666 -667/** -668 * Set the value of nexusAnalyzerEnabled. -669 * -670 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled -671 */ -672publicvoid setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) { -673this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; -674 } -675 -676/** -677 * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local). +663private Boolean centralAnalyzerEnabled; +664 +665/** +666 * Get the value of centralAnalyzerEnabled. +667 * +668 * @return the value of centralAnalyzerEnabled +669 */ +670public Boolean isCentralAnalyzerEnabled() { +671return centralAnalyzerEnabled; +672 } +673 +674/** +675 * Set the value of centralAnalyzerEnabled. +676 * +677 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled678 */ -679private String nexusUrl; -680 -681/** -682 * Get the value of nexusUrl. -683 * -684 * @return the value of nexusUrl +679publicvoid setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) { +680this.centralAnalyzerEnabled = centralAnalyzerEnabled; +681 } +682 +683/** +684 * Whether or not the nexus analyzer is enabled.685 */ -686public String getNexusUrl() { -687return nexusUrl; -688 } -689 -690/** -691 * Set the value of nexusUrl. -692 * -693 * @param nexusUrl new value of nexusUrl -694 */ -695publicvoid setNexusUrl(String nexusUrl) { -696this.nexusUrl = nexusUrl; -697 } -698/** -699 * Whether or not the defined proxy should be used when connecting to Nexus. -700 */ -701private Boolean nexusUsesProxy; -702 -703/** -704 * Get the value of nexusUsesProxy. -705 * -706 * @return the value of nexusUsesProxy -707 */ -708public Boolean isNexusUsesProxy() { -709return nexusUsesProxy; -710 } +686private Boolean nexusAnalyzerEnabled; +687 +688/** +689 * Get the value of nexusAnalyzerEnabled. +690 * +691 * @return the value of nexusAnalyzerEnabled +692 */ +693public Boolean isNexusAnalyzerEnabled() { +694return nexusAnalyzerEnabled; +695 } +696 +697/** +698 * Set the value of nexusAnalyzerEnabled. +699 * +700 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled +701 */ +702publicvoid setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) { +703this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; +704 } +705 +706/** +707 * The URL of a Nexus server's REST API end point +708 * (http://domain/nexus/service/local). +709 */ +710private String nexusUrl; 711712/** -713 * Set the value of nexusUsesProxy. +713 * Get the value of nexusUrl.714 * -715 * @param nexusUsesProxy new value of nexusUsesProxy +715 * @return the value of nexusUrl716 */ -717publicvoid setNexusUsesProxy(Boolean nexusUsesProxy) { -718this.nexusUsesProxy = nexusUsesProxy; +717public String getNexusUrl() { +718return nexusUrl; 719 } 720721/** -722 * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP -723 * files. -724 */ -725private String zipExtensions; -726 -727/** -728 * Get the value of zipExtensions. -729 * -730 * @return the value of zipExtensions +722 * Set the value of nexusUrl. +723 * +724 * @param nexusUrl new value of nexusUrl +725 */ +726publicvoid setNexusUrl(String nexusUrl) { +727this.nexusUrl = nexusUrl; +728 } +729/** +730 * Whether or not the defined proxy should be used when connecting to Nexus.731 */ -732public String getZipExtensions() { -733return zipExtensions; -734 } -735 -736/** -737 * Set the value of zipExtensions. -738 * -739 * @param zipExtensions new value of zipExtensions -740 */ -741publicvoid setZipExtensions(String zipExtensions) { -742this.zipExtensions = zipExtensions; -743 } -744 -745/** -746 * The path to Mono for .NET assembly analysis on non-windows systems. +732private Boolean nexusUsesProxy; +733 +734/** +735 * Get the value of nexusUsesProxy. +736 * +737 * @return the value of nexusUsesProxy +738 */ +739public Boolean isNexusUsesProxy() { +740return nexusUsesProxy; +741 } +742 +743/** +744 * Set the value of nexusUsesProxy. +745 * +746 * @param nexusUsesProxy new value of nexusUsesProxy747 */ -748private String pathToMono; -749 -750/** -751 * Get the value of pathToMono. -752 * -753 * @return the value of pathToMono -754 */ -755public String getPathToMono() { -756return pathToMono; -757 } -758 -759/** -760 * Set the value of pathToMono. -761 * -762 * @param pathToMono new value of pathToMono -763 */ -764publicvoid setPathToMono(String pathToMono) { -765this.pathToMono = pathToMono; -766 } -767 -768 @Override -769publicvoid execute() throws BuildException { -770 dealWithReferences(); -771 validateConfiguration(); -772 populateSettings(); -773 Engine engine = null; -774try { -775 engine = new Engine(Check.class.getClassLoader()); -776if (isUpdateOnly()) { -777 log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN); -778 engine.doUpdates(); -779 } else { -780try { -781for (Resource resource : path) { -782final FileProvider provider = resource.as(FileProvider.class); -783if (provider != null) { -784final File file = provider.getFile(); -785if (file != null && file.exists()) { -786 engine.scan(file); -787 } -788 } -789 } -790 -791 engine.analyzeDependencies(); -792 DatabaseProperties prop = null; -793 CveDB cve = null; -794try { -795 cve = new CveDB(); -796 cve.open(); -797 prop = cve.getDatabaseProperties(); -798 } catch (DatabaseException ex) { -799 log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); -800 } finally { -801if (cve != null) { -802 cve.close(); -803 } -804 } -805final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); -806 reporter.generateReports(reportOutputDirectory, reportFormat); -807 -808if (this.failBuildOnCVSS <= 10) { -809 checkForFailure(engine.getDependencies()); -810 } -811if (this.showSummary) { -812 showSummary(engine.getDependencies()); -813 } -814 } catch (IOException ex) { -815 log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG); -816thrownew BuildException("Unable to generate dependency-check report", ex); -817 } catch (Exception ex) { -818 log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG); -819thrownew BuildException("An exception occurred; unable to continue task", ex); -820 } -821 } -822 } catch (DatabaseException ex) { -823 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR); -824 } finally { -825 Settings.cleanup(true); -826if (engine != null) { -827 engine.cleanup(); -828 } -829 } -830 } -831 -832/** -833 * Validate the configuration to ensure the parameters have been properly configured/initialized. -834 * -835 * @throws BuildException if the task was not configured correctly. -836 */ -837privatevoid validateConfiguration() throws BuildException { -838if (path == null) { -839thrownew BuildException("No project dependencies have been defined to analyze."); -840 } -841if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { -842thrownew BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); -843 } -844 } -845 -846/** -847 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -848 * required to change the proxy server, port, and connection timeout. -849 * -850 * @throws BuildException thrown when an invalid setting is configured. -851 */ -852 @Override -853protectedvoid populateSettings() throws BuildException { -854super.populateSettings(); -855 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); -856 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -857 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); -858 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); -859 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); -860 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); -861 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); -862 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); -863 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); -864 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); -865 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); -866 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); -867 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -868 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -869 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); -870 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); -871 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -872 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -873 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -874 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -875 } -876 -877/** -878 * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the -879 * configuration. -880 * -881 * @param dependencies the list of dependency objects -882 * @throws BuildException thrown if a CVSS score is found that is higher then the threshold set -883 */ -884privatevoid checkForFailure(List<Dependency> dependencies) throws BuildException { -885final StringBuilder ids = new StringBuilder(); -886for (Dependency d : dependencies) { -887for (Vulnerability v : d.getVulnerabilities()) { -888if (v.getCvssScore() >= failBuildOnCVSS) { -889if (ids.length() == 0) { -890 ids.append(v.getName()); -891 } else { -892 ids.append(", ").append(v.getName()); -893 } -894 } -895 } -896 } -897if (ids.length() > 0) { -898final String msg = String.format("%n%nDependency-Check Failure:%n" -899 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -900 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -901thrownew BuildException(msg); -902 } -903 } -904 -905/** -906 * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. -907 * -908 * @param dependencies a list of dependency objects -909 */ -910privatevoid showSummary(List<Dependency> dependencies) { -911final StringBuilder summary = new StringBuilder(); -912for (Dependency d : dependencies) { -913boolean firstEntry = true; -914final StringBuilder ids = new StringBuilder(); -915for (Vulnerability v : d.getVulnerabilities()) { -916if (firstEntry) { -917 firstEntry = false; -918 } else { -919 ids.append(", "); -920 } -921 ids.append(v.getName()); -922 } -923if (ids.length() > 0) { -924 summary.append(d.getFileName()).append(" ("); -925 firstEntry = true; -926for (Identifier id : d.getIdentifiers()) { -927if (firstEntry) { -928 firstEntry = false; -929 } else { -930 summary.append(", "); -931 } -932 summary.append(id.getValue()); -933 } -934 summary.append(") : ").append(ids).append(NEW_LINE); -935 } -936 } -937if (summary.length() > 0) { -938final String msg = String.format("%n%n" -939 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" -940 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); -941 log(msg, Project.MSG_WARN); -942 } -943 } -944 -945/** -946 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", etc.. -947 */ -948publicstaticclassReportFormatsextends EnumeratedAttribute { -949 -950/** -951 * Returns the list of values for the report format. -952 * -953 * @return the list of values for the report format -954 */ -955 @Override -956public String[] getValues() { -957int i = 0; -958final Format[] formats = Format.values(); -959final String[] values = new String[formats.length]; -960for (Format format : formats) { -961 values[i++] = format.name(); -962 } -963return values; -964 } -965 } -966 } +748publicvoid setNexusUsesProxy(Boolean nexusUsesProxy) { +749this.nexusUsesProxy = nexusUsesProxy; +750 } +751 +752/** +753 * Additional ZIP File extensions to add analyze. This should be a +754 * comma-separated list of file extensions to treat like ZIP files. +755 */ +756private String zipExtensions; +757 +758/** +759 * Get the value of zipExtensions. +760 * +761 * @return the value of zipExtensions +762 */ +763public String getZipExtensions() { +764return zipExtensions; +765 } +766 +767/** +768 * Set the value of zipExtensions. +769 * +770 * @param zipExtensions new value of zipExtensions +771 */ +772publicvoid setZipExtensions(String zipExtensions) { +773this.zipExtensions = zipExtensions; +774 } +775 +776/** +777 * The path to Mono for .NET assembly analysis on non-windows systems. +778 */ +779private String pathToMono; +780 +781/** +782 * Get the value of pathToMono. +783 * +784 * @return the value of pathToMono +785 */ +786public String getPathToMono() { +787return pathToMono; +788 } +789 +790/** +791 * Set the value of pathToMono. +792 * +793 * @param pathToMono new value of pathToMono +794 */ +795publicvoid setPathToMono(String pathToMono) { +796this.pathToMono = pathToMono; +797 } +798 +799 @Override +800publicvoid execute() throws BuildException { +801 dealWithReferences(); +802 validateConfiguration(); +803 populateSettings(); +804 Engine engine = null; +805try { +806 engine = new Engine(Check.class.getClassLoader()); +807if (isUpdateOnly()) { +808 log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN); +809 engine.doUpdates(); +810 } else { +811try { +812for (Resource resource : path) { +813final FileProvider provider = resource.as(FileProvider.class); +814if (provider != null) { +815final File file = provider.getFile(); +816if (file != null && file.exists()) { +817 engine.scan(file); +818 } +819 } +820 } +821 +822 engine.analyzeDependencies(); +823 DatabaseProperties prop = null; +824 CveDB cve = null; +825try { +826 cve = new CveDB(); +827 cve.open(); +828 prop = cve.getDatabaseProperties(); +829 } catch (DatabaseException ex) { +830 log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); +831 } finally { +832if (cve != null) { +833 cve.close(); +834 } +835 } +836final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); +837 reporter.generateReports(reportOutputDirectory, reportFormat); +838 +839if (this.failBuildOnCVSS <= 10) { +840 checkForFailure(engine.getDependencies()); +841 } +842if (this.showSummary) { +843 showSummary(engine.getDependencies()); +844 } +845 } catch (IOException ex) { +846 log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG); +847thrownew BuildException("Unable to generate dependency-check report", ex); +848 } catch (Exception ex) { +849 log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG); +850thrownew BuildException("An exception occurred; unable to continue task", ex); +851 } +852 } +853 } catch (DatabaseException ex) { +854 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR); +855 } finally { +856 Settings.cleanup(true); +857if (engine != null) { +858 engine.cleanup(); +859 } +860 } +861 } +862 +863/** +864 * Validate the configuration to ensure the parameters have been properly +865 * configured/initialized. +866 * +867 * @throws BuildException if the task was not configured correctly. +868 */ +869privatevoid validateConfiguration() throws BuildException { +870if (path == null) { +871thrownew BuildException("No project dependencies have been defined to analyze."); +872 } +873if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { +874thrownew BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); +875 } +876 } +877 +878/** +879 * Takes the properties supplied and updates the dependency-check settings. +880 * Additionally, this sets the system properties required to change the +881 * proxy server, port, and connection timeout. +882 * +883 * @throws BuildException thrown when an invalid setting is configured. +884 */ +885 @Override +886protectedvoid populateSettings() throws BuildException { +887super.populateSettings(); +888 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); +889 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +890 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); +891 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); +892 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); +893 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); +894 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); +895 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); +896 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); +897 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); +898 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); +899 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +900 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); +901 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +902 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +903 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); +904 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); +905 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +906 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +907 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +908 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +909 } +910 +911/** +912 * Checks to see if a vulnerability has been identified with a CVSS score +913 * that is above the threshold set in the configuration. +914 * +915 * @param dependencies the list of dependency objects +916 * @throws BuildException thrown if a CVSS score is found that is higher +917 * then the threshold set +918 */ +919privatevoid checkForFailure(List<Dependency> dependencies) throws BuildException { +920final StringBuilder ids = new StringBuilder(); +921for (Dependency d : dependencies) { +922for (Vulnerability v : d.getVulnerabilities()) { +923if (v.getCvssScore() >= failBuildOnCVSS) { +924if (ids.length() == 0) { +925 ids.append(v.getName()); +926 } else { +927 ids.append(", ").append(v.getName()); +928 } +929 } +930 } +931 } +932if (ids.length() > 0) { +933final String msg = String.format("%n%nDependency-Check Failure:%n" +934 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +935 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +936thrownew BuildException(msg); +937 } +938 } +939 +940/** +941 * Generates a warning message listing a summary of dependencies and their +942 * associated CPE and CVE entries. +943 * +944 * @param dependencies a list of dependency objects +945 */ +946privatevoid showSummary(List<Dependency> dependencies) { +947final StringBuilder summary = new StringBuilder(); +948for (Dependency d : dependencies) { +949boolean firstEntry = true; +950final StringBuilder ids = new StringBuilder(); +951for (Vulnerability v : d.getVulnerabilities()) { +952if (firstEntry) { +953 firstEntry = false; +954 } else { +955 ids.append(", "); +956 } +957 ids.append(v.getName()); +958 } +959if (ids.length() > 0) { +960 summary.append(d.getFileName()).append(" ("); +961 firstEntry = true; +962for (Identifier id : d.getIdentifiers()) { +963if (firstEntry) { +964 firstEntry = false; +965 } else { +966 summary.append(", "); +967 } +968 summary.append(id.getValue()); +969 } +970 summary.append(") : ").append(ids).append(NEW_LINE); +971 } +972 } +973if (summary.length() > 0) { +974final String msg = String.format("%n%n" +975 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" +976 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); +977 log(msg, Project.MSG_WARN); +978 } +979 } +980 +981/** +982 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", +983 * etc.. +984 */ +985publicstaticclassReportFormatsextends EnumeratedAttribute { +986 +987/** +988 * Returns the list of values for the report format. +989 * +990 * @return the list of values for the report format +991 */ +992 @Override +993public String[] getValues() { +994int i = 0; +995final Format[] formats = Format.values(); +996final String[] values = new String[formats.length]; +997for (Format format : formats) { +998 values[i++] = format.name(); +999 } +1000return values; +1001 } +1002 } +1003 }
      diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-frame.html b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-frame.html index 2da99250a..b63485c6d 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-frame.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-summary.html b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-summary.html index 9bb3b2a16..82c23676f 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/dependency-check-ant/xref/org/slf4j/impl/StaticLoggerBinder.html b/dependency-check-ant/xref/org/slf4j/impl/StaticLoggerBinder.html index c5dee726a..fcae5d356 100644 --- a/dependency-check-ant/xref/org/slf4j/impl/StaticLoggerBinder.html +++ b/dependency-check-ant/xref/org/slf4j/impl/StaticLoggerBinder.html @@ -31,84 +31,95 @@ 23import org.slf4j.spi.LoggerFactoryBinder; 2425/** -26 * The binding of org.slf4j.LoggerFactory class with an actual instance of org.slf4j.ILoggerFactory is performed using information -27 * returned by this class. -28 * -29 * @author colezlaw -30 */ -31publicclassStaticLoggerBinderimplements LoggerFactoryBinder { -32 -33/** -34 * The unique instance of this class -35 * -36 */ -37privatestaticfinalStaticLoggerBinder SINGLETON = newStaticLoggerBinder(); -38 -39/** -40 * Return the singleton of this class. -41 * -42 * @return the StaticLoggerBinder singleton -43 */ -44publicstaticfinalStaticLoggerBinder getSingleton() { -45return SINGLETON; -46 } -47 -48/** -49 * Ant tasks have the log method we actually want to call. So we hang onto the task as a delegate -50 */ -51private Task task = null; -52 -53/** -54 * Set the Task which will this is to log through. -55 * -56 * @param task the task through which to log -57 */ -58publicvoid setTask(Task task) { -59this.task = task; -60 loggerFactory = newAntLoggerFactory(task); -61 } -62 -63/** -64 * Declare the version of the SLF4J API this implementation is compiled against. The value of this filed is usually modified -65 * with each release. -66 */ -67// to avoid constant folding by the compiler, this field must *not* be final -68publicstatic String REQUESTED_API_VERSION = "1.7.12"; // final -69 -70privatestaticfinal String LOGGER_FACTORY_CLASS = AntLoggerFactory.class.getName(); -71 -72/** -73 * The ILoggerFactory instance returned by the {@link #getLoggerFactory} method should always be the smae object -74 */ -75private ILoggerFactory loggerFactory; +26 * The binding of org.slf4j.LoggerFactory class with an actual instance of +27 * org.slf4j.ILoggerFactory is performed using information returned by this +28 * class. +29 * +30 * @author colezlaw +31 */ +32//CSOFF: FinalClass +33publicclassStaticLoggerBinderimplements LoggerFactoryBinder { +34//CSON: FinalClass +35 +36/** +37 * The unique instance of this class +38 */ +39privatestaticfinalStaticLoggerBinder SINGLETON = newStaticLoggerBinder(); +40 +41/** +42 * Return the singleton of this class. +43 * +44 * @return the StaticLoggerBinder singleton +45 */ +46publicstaticfinalStaticLoggerBinder getSingleton() { +47return SINGLETON; +48 } +49 +50/** +51 * Ant tasks have the log method we actually want to call. So we hang onto +52 * the task as a delegate +53 */ +54private Task task = null; +55 +56/** +57 * Set the Task which will this is to log through. +58 * +59 * @param task the task through which to log +60 */ +61publicvoid setTask(Task task) { +62this.task = task; +63 loggerFactory = newAntLoggerFactory(task); +64 } +65 +66/** +67 * Declare the version of the SLF4J API this implementation is compiled +68 * against. The value of this filed is usually modified with each release. +69 */ +70// to avoid constant folding by the compiler, this field must *not* be final +71//CSOFF: StaticVariableName +72//CSOFF: VisibilityModifier +73publicstatic String REQUESTED_API_VERSION = "1.7.12"; // final +74//CSON: VisibilityModifier +75//CSON: StaticVariableName7677/** -78 * Constructs a new static logger binder. +78 * The logger factory class string.79 */ -80privateStaticLoggerBinder() { -81 loggerFactory = newAntLoggerFactory(task); -82 } -83 -84/** -85 * Returns the logger factory. -86 * -87 * @return the logger factory -88 */ -89 @Override -90public ILoggerFactory getLoggerFactory() { -91return loggerFactory; -92 } -93 -94/** -95 * Returns the logger factory class string. -96 * -97 * @return the logger factory class string -98 */ -99 @Override -100public String getLoggerFactoryClassStr() { -101return LOGGER_FACTORY_CLASS; -102 } -103 } +80privatestaticfinal String LOGGER_FACTORY_CLASS = AntLoggerFactory.class.getName(); +81 +82/** +83 * The ILoggerFactory instance returned by the {@link #getLoggerFactory} +84 * method should always be the smae object +85 */ +86private ILoggerFactory loggerFactory; +87 +88/** +89 * Constructs a new static logger binder. +90 */ +91privateStaticLoggerBinder() { +92 loggerFactory = newAntLoggerFactory(task); +93 } +94 +95/** +96 * Returns the logger factory. +97 * +98 * @return the logger factory +99 */ +100 @Override +101public ILoggerFactory getLoggerFactory() { +102return loggerFactory; +103 } +104 +105/** +106 * Returns the logger factory class string. +107 * +108 * @return the logger factory class string +109 */ +110 @Override +111public String getLoggerFactoryClassStr() { +112return LOGGER_FACTORY_CLASS; +113 } +114 }
      diff --git a/dependency-check-ant/xref/org/slf4j/impl/package-frame.html b/dependency-check-ant/xref/org/slf4j/impl/package-frame.html index c09b0bce6..b74e9fb84 100644 --- a/dependency-check-ant/xref/org/slf4j/impl/package-frame.html +++ b/dependency-check-ant/xref/org/slf4j/impl/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference Package org.slf4j.impl + Dependency-Check Ant Task 1.4.0 Reference Package org.slf4j.impl diff --git a/dependency-check-ant/xref/org/slf4j/impl/package-summary.html b/dependency-check-ant/xref/org/slf4j/impl/package-summary.html index 0a4e67614..1474d553a 100644 --- a/dependency-check-ant/xref/org/slf4j/impl/package-summary.html +++ b/dependency-check-ant/xref/org/slf4j/impl/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference Package org.slf4j.impl + Dependency-Check Ant Task 1.4.0 Reference Package org.slf4j.impl diff --git a/dependency-check-ant/xref/overview-frame.html b/dependency-check-ant/xref/overview-frame.html index 79914866d..e51b8b623 100644 --- a/dependency-check-ant/xref/overview-frame.html +++ b/dependency-check-ant/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference + Dependency-Check Ant Task 1.4.0 Reference diff --git a/dependency-check-ant/xref/overview-summary.html b/dependency-check-ant/xref/overview-summary.html index dfd95093e..744480468 100644 --- a/dependency-check-ant/xref/overview-summary.html +++ b/dependency-check-ant/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.3.6 Reference + Dependency-Check Ant Task 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Ant Task 1.3.6 Reference

      +

      Dependency-Check Ant Task 1.4.0 Reference

      diff --git a/dependency-check-cli/apidocs/allclasses-frame.html b/dependency-check-cli/apidocs/allclasses-frame.html index 97f859e44..6a7938eab 100644 --- a/dependency-check-cli/apidocs/allclasses-frame.html +++ b/dependency-check-cli/apidocs/allclasses-frame.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Command Line 1.3.6 API) - +All Classes (Dependency-Check Command Line 1.4.0 API) + diff --git a/dependency-check-cli/apidocs/allclasses-noframe.html b/dependency-check-cli/apidocs/allclasses-noframe.html index 61a519b13..876d89003 100644 --- a/dependency-check-cli/apidocs/allclasses-noframe.html +++ b/dependency-check-cli/apidocs/allclasses-noframe.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Command Line 1.3.6 API) - +All Classes (Dependency-Check Command Line 1.4.0 API) + diff --git a/dependency-check-cli/apidocs/constant-values.html b/dependency-check-cli/apidocs/constant-values.html index e35cdbd0f..08f9fc6d1 100644 --- a/dependency-check-cli/apidocs/constant-values.html +++ b/dependency-check-cli/apidocs/constant-values.html @@ -2,10 +2,10 @@ - + -Constant Field Values (Dependency-Check Command Line 1.3.6 API) - +Constant Field Values (Dependency-Check Command Line 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,13 +13,13 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html index 162cdf3fc..76e02745f 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck (Dependency-Check Command Line 1.3.6 API) - +org.owasp.dependencycheck (Dependency-Check Command Line 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ - + diff --git a/dependency-check-cli/cobertura/frame-summary.html b/dependency-check-cli/cobertura/frame-summary.html index 1fd99115d..fed446866 100644 --- a/dependency-check-cli/cobertura/frame-summary.html +++ b/dependency-check-cli/cobertura/frame-summary.html @@ -16,8 +16,8 @@
      - - + +
      Package # Classes Line Coverage Branch Coverage Complexity
      All Packages4
      45%
      286/627
      19%
      56/284
      2.946
      org.owasp.dependencycheck4
      45%
      286/627
      19%
      56/284
      2.946
      All Packages4
      45%
      288/631
      19%
      56/284
      2.92
      org.owasp.dependencycheck4
      45%
      288/631
      19%
      56/284
      2.92
      - + diff --git a/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html b/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html index e7caecec0..acdd31361 100644 --- a/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html +++ b/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      App
      10%
      27/255
      9%
      10/104
      7.75
      App
      10%
      27/256
      9%
      10/104
      7.75
       
      @@ -109,7 +109,7 @@
        * @author Jeremy Long
       46  
        */
      -  47  2
       public class App {
      +  47  4
       public class App {
       48  
       
       49   @@ -118,7 +118,7 @@
            * The logger.
       51  
            */
      -  52  1
           private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
      +  52  2
           private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
       53  
       
       54   @@ -207,7 +207,8 @@  110  0
                       } catch (IOException ex) {
       111  0
                           LOGGER.error("Unable to delete the database");
       112  0
                       }
      -  113  0
                   }
      +  113   +
                   }
       114  0
               } else if (cli.isGetVersion()) {
       115  0
                   cli.printVersionInfo();
       116  0
               } else if (cli.isUpdateOnly()) {
      @@ -437,217 +438,219 @@  280  0
               final String cveBase12 = cli.getBaseCve12Url();
       281  0
               final String cveBase20 = cli.getBaseCve20Url();
       282  0
               final Integer cveValidForHours = cli.getCveValidForHours();
      -  283   +  283  0
               final boolean experimentalEnabled = cli.isExperimentalEnabled();
      +  284  
       
      -  284  0
               if (propertiesFile != null) {
      -  285   +  285  0
               if (propertiesFile != null) {
      +  286  
                   try {
      -  286  0
                       Settings.mergeProperties(propertiesFile);
      -  287  0
                   } catch (FileNotFoundException ex) {
      -  288  0
                       LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath());
      -  289  0
                       LOGGER.debug("", ex);
      -  290  0
                   } catch (IOException ex) {
      -  291  0
                       LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath());
      -  292  0
                       LOGGER.debug("", ex);
      -  293  0
                   }
      -  294   -
               }
      +  287  0
                       Settings.mergeProperties(propertiesFile);
      +  288  0
                   } catch (FileNotFoundException ex) {
      +  289  0
                       LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath());
      +  290  0
                       LOGGER.debug("", ex);
      +  291  0
                   } catch (IOException ex) {
      +  292  0
                       LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath());
      +  293  0
                       LOGGER.debug("", ex);
      +  294  0
                   }
       295   -
               // We have to wait until we've merged the properties before attempting to set whether we use
      +
               }
       296   -
               // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated
      +
               // We have to wait until we've merged the properties before attempting to set whether we use
       297   +
               // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated
      +  298  
               // on the command line
      -  298  0
               final boolean nexusUsesProxy = cli.isNexusUsesProxy();
      -  299  0
               if (dataDirectory != null) {
      -  300  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
      -  301  0
               } else if (System.getProperty("basedir") != null) {
      -  302  0
                   final File dataDir = new File(System.getProperty("basedir"), "data");
      -  303  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      -  304  0
               } else {
      -  305  0
                   final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath());
      -  306  0
                   final File base = jarPath.getParentFile();
      -  307  0
                   final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      -  308  0
                   final File dataDir = new File(base, sub);
      -  309  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      -  310   +  299  0
               final boolean nexusUsesProxy = cli.isNexusUsesProxy();
      +  300  0
               if (dataDirectory != null) {
      +  301  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
      +  302  0
               } else if (System.getProperty("basedir") != null) {
      +  303  0
                   final File dataDir = new File(System.getProperty("basedir"), "data");
      +  304  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      +  305  0
               } else {
      +  306  0
                   final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath());
      +  307  0
                   final File base = jarPath.getParentFile();
      +  308  0
                   final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      +  309  0
                   final File dataDir = new File(base, sub);
      +  310  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      +  311  
               }
      -  311  0
               Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
      -  312  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
      -  313  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
      -  314  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser);
      -  315  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass);
      -  316  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
      -  317  0
               Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
      -  318  0
               Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
      -  319   -
       
      +  312  0
               Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
      +  313  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
      +  314  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
      +  315  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser);
      +  316  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass);
      +  317  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
      +  318  0
               Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
      +  319  0
               Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
       320   +
       
      +  321  
               //File Type Analyzer Settings
      -  321  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled());
      -  322  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled());
      -  323  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled());
      -  324  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled());
      -  325  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled());
      -  326  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled());
      -  327  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled());
      -  328  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled());
      -  329  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled());
      -  330  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled());
      -  331  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled());
      -  332  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled());
      -  333  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled());
      -  334  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled());
      -  335  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled());
      -  336   +  322  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled);
      +  323  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled());
      +  324  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled());
      +  325  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled());
      +  326  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled());
      +  327  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled());
      +  328  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled());
      +  329  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled());
      +  330  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled());
      +  331  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled());
      +  332  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled());
      +  333  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled());
      +  334  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled());
      +  335  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled());
      +  336  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled());
      +  337  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled());
      +  338  
       
      -  337  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit());
      -  338  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
      -  339  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
      -  340  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
      -  341  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
      -  342  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
      -  343  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
      -  344  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
      -  345  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
      -  346  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
      -  347  0
               if (cveBase12 != null && !cveBase12.isEmpty()) {
      -  348  0
                   Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12);
      -  349  0
                   Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20);
      -  350  0
                   Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12);
      -  351  0
                   Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20);
      -  352   -
               }
      -  353  0
           }
      +  339  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit());
      +  340  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
      +  341  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
      +  342  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
      +  343  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
      +  344  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
      +  345  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
      +  346  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
      +  347  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
      +  348  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
      +  349  0
               if (cveBase12 != null && !cveBase12.isEmpty()) {
      +  350  0
                   Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12);
      +  351  0
                   Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20);
      +  352  0
                   Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12);
      +  353  0
                   Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20);
       354   -
       
      -  355   -
           /**
      +
               }
      +  355  0
           }
       356   -
            * Creates a file appender and adds it to logback.
      +
       
       357   -
            *
      +
           /**
       358   -
            * @param verboseLog the path to the verbose log file
      +
            * Creates a file appender and adds it to logback.
       359   -
            */
      +
            *
       360   +
            * @param verboseLog the path to the verbose log file
      +  361   +
            */
      +  362  
           private void prepareLogger(String verboseLog) {
      -  361  0
               final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton();
      -  362  0
               final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory();
      -  363   +  363  0
               final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton();
      +  364  0
               final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory();
      +  365  
       
      -  364  0
               final PatternLayoutEncoder encoder = new PatternLayoutEncoder();
      -  365  0
               encoder.setPattern("%d %C:%L%n%-5level - %msg%n");
      -  366  0
               encoder.setContext(context);
      -  367  0
               encoder.start();
      -  368  0
               final FileAppender fa = new FileAppender();
      -  369  0
               fa.setAppend(true);
      -  370  0
               fa.setEncoder(encoder);
      -  371  0
               fa.setContext(context);
      -  372  0
               fa.setFile(verboseLog);
      -  373  0
               final File f = new File(verboseLog);
      -  374  0
               String name = f.getName();
      -  375  0
               final int i = name.lastIndexOf('.');
      -  376  0
               if (i > 1) {
      -  377  0
                   name = name.substring(0, i);
      -  378   +  366  0
               final PatternLayoutEncoder encoder = new PatternLayoutEncoder();
      +  367  0
               encoder.setPattern("%d %C:%L%n%-5level - %msg%n");
      +  368  0
               encoder.setContext(context);
      +  369  0
               encoder.start();
      +  370  0
               final FileAppender fa = new FileAppender();
      +  371  0
               fa.setAppend(true);
      +  372  0
               fa.setEncoder(encoder);
      +  373  0
               fa.setContext(context);
      +  374  0
               fa.setFile(verboseLog);
      +  375  0
               final File f = new File(verboseLog);
      +  376  0
               String name = f.getName();
      +  377  0
               final int i = name.lastIndexOf('.');
      +  378  0
               if (i > 1) {
      +  379  0
                   name = name.substring(0, i);
      +  380  
               }
      -  379  0
               fa.setName(name);
      -  380  0
               fa.start();
      -  381  0
               final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
      -  382  0
               rootLogger.addAppender(fa);
      -  383  0
           }
      -  384   -
       
      -  385   -
           /**
      +  381  0
               fa.setName(name);
      +  382  0
               fa.start();
      +  383  0
               final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
      +  384  0
               rootLogger.addAppender(fa);
      +  385  0
           }
       386   -
            * Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style
      +
       
       387   -
            * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first *
      -  388   -
            * or ?).
      -  389   -
            *
      -  390   -
            * @param path the path to canonicalize
      -  391   -
            * @return the canonical path
      -  392   -
            */
      -  393   -
           protected String ensureCanonicalPath(String path) {
      -  394  2
               String basePath = null;
      -  395  2
               String wildCards = null;
      -  396  2
               final String file = path.replace('\\', '/');
      -  397  2
               if (file.contains("*") || file.contains("?")) {
      -  398   -
       
      -  399  1
                   int pos = getLastFileSeparator(file);
      -  400  1
                   if (pos < 0) {
      -  401  0
                       return file;
      -  402   -
                   }
      -  403  1
                   pos += 1;
      -  404  1
                   basePath = file.substring(0, pos);
      -  405  1
                   wildCards = file.substring(pos);
      -  406  1
               } else {
      -  407  1
                   basePath = file;
      -  408   -
               }
      -  409   -
       
      -  410  2
               File f = new File(basePath);
      -  411   -
               try {
      -  412  2
                   f = f.getCanonicalFile();
      -  413  2
                   if (wildCards != null) {
      -  414  1
                       f = new File(f, wildCards);
      -  415   -
                   }
      -  416  0
               } catch (IOException ex) {
      -  417  0
                   LOGGER.warn("Invalid path '{}' was provided.", path);
      -  418  0
                   LOGGER.debug("Invalid path provided", ex);
      -  419  2
               }
      -  420  2
               return f.getAbsolutePath().replace('\\', '/');
      -  421   -
           }
      -  422   -
       
      -  423  
           /**
      -  424   -
            * Returns the position of the last file separator.
      -  425   +  388   +
            * Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style
      +  389   +
            * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first *
      +  390   +
            * or ?).
      +  391  
            *
      -  426   -
            * @param file a file path
      -  427   -
            * @return the position of the last file separator
      -  428   +  392   +
            * @param path the path to canonicalize
      +  393   +
            * @return the canonical path
      +  394  
            */
      -  429   -
           private int getLastFileSeparator(String file) {
      -  430  1
               if (file.contains("*") || file.contains("?")) {
      -  431  1
                   int p1 = file.indexOf('*');
      -  432  1
                   int p2 = file.indexOf('?');
      -  433  1
                   p1 = p1 > 0 ? p1 : file.length();
      -  434  1
                   p2 = p2 > 0 ? p2 : file.length();
      -  435  1
                   int pos = p1 < p2 ? p1 : p2;
      -  436  1
                   pos = file.lastIndexOf('/', pos);
      -  437  1
                   return pos;
      -  438   -
               } else {
      -  439  0
                   return file.lastIndexOf('/');
      -  440   +  395   +
           protected String ensureCanonicalPath(String path) {
      +  396  4
               String basePath = null;
      +  397  4
               String wildCards = null;
      +  398  4
               final String file = path.replace('\\', '/');
      +  399  4
               if (file.contains("*") || file.contains("?")) {
      +  400   +
       
      +  401  2
                   int pos = getLastFileSeparator(file);
      +  402  2
                   if (pos < 0) {
      +  403  0
                       return file;
      +  404   +
                   }
      +  405  2
                   pos += 1;
      +  406  2
                   basePath = file.substring(0, pos);
      +  407  2
                   wildCards = file.substring(pos);
      +  408  2
               } else {
      +  409  2
                   basePath = file;
      +  410  
               }
      -  441   +  411   +
       
      +  412  4
               File f = new File(basePath);
      +  413   +
               try {
      +  414  4
                   f = f.getCanonicalFile();
      +  415  4
                   if (wildCards != null) {
      +  416  2
                       f = new File(f, wildCards);
      +  417   +
                   }
      +  418  0
               } catch (IOException ex) {
      +  419  0
                   LOGGER.warn("Invalid path '{}' was provided.", path);
      +  420  0
                   LOGGER.debug("Invalid path provided", ex);
      +  421  4
               }
      +  422  4
               return f.getAbsolutePath().replace('\\', '/');
      +  423  
           }
      +  424   +
       
      +  425   +
           /**
      +  426   +
            * Returns the position of the last file separator.
      +  427   +
            *
      +  428   +
            * @param file a file path
      +  429   +
            * @return the position of the last file separator
      +  430   +
            */
      +  431   +
           private int getLastFileSeparator(String file) {
      +  432  2
               if (file.contains("*") || file.contains("?")) {
      +  433  2
                   int p1 = file.indexOf('*');
      +  434  2
                   int p2 = file.indexOf('?');
      +  435  2
                   p1 = p1 > 0 ? p1 : file.length();
      +  436  2
                   p2 = p2 > 0 ? p2 : file.length();
      +  437  2
                   int pos = p1 < p2 ? p1 : p2;
      +  438  2
                   pos = file.lastIndexOf('/', pos);
      +  439  2
                   return pos;
      +  440   +
               } else {
      +  441  0
                   return file.lastIndexOf('/');
       442   +
               }
      +  443   +
           }
      +  444  
       }
      - + diff --git a/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html b/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html index 82bacb498..0a3ad314f 100644 --- a/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html +++ b/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html @@ -12,8 +12,8 @@
       
      - - + +
      Classes in this File Line Coverage Branch Coverage Complexity
      CliParser
      71%
      259/363
      25%
      46/180
      2.452
      CliParser$ARGUMENT
      0%
      0/1
      N/A
      2.452
      CliParser
      71%
      261/366
      25%
      46/180
      2.429
      CliParser$ARGUMENT
      0%
      0/1
      N/A
      2.429
       
      @@ -100,7 +100,7 @@
        * @author Jeremy Long
       41  
        */
      -  42  9
       public final class CliParser {
      +  42  18
       public final class CliParser {
       43  
       
       44   @@ -109,7 +109,7 @@
            * The logger.
       46  
            */
      -  47  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CliParser.class);
      +  47  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CliParser.class);
       48  
           /**
       49   @@ -124,7 +124,7 @@
            * Indicates whether the arguments are valid.
       54  
            */
      -  55  9
           private boolean isValid = true;
      +  55  18
           private boolean isValid = true;
       56  
       
       57   @@ -136,774 +136,773 @@  60  
            * @param args the command line arguments
       61   -
            * @throws FileNotFoundException is thrown when a 'file' argument does not point to a file that exists.
      +
            * @throws FileNotFoundException is thrown when a 'file' argument does not
       62   -
            * @throws ParseException is thrown when a Parse Exception occurs.
      +
            * point to a file that exists.
       63   -
            */
      +
            * @throws ParseException is thrown when a Parse Exception occurs.
       64   +
            */
      +  65  
           public void parse(String[] args) throws FileNotFoundException, ParseException {
      -  65  9
               line = parseArgs(args);
      -  66   +  66  18
               line = parseArgs(args);
      +  67  
       
      -  67  7
               if (line != null) {
      -  68  7
                   validateArgs();
      -  69   +  68  14
               if (line != null) {
      +  69  14
                   validateArgs();
      +  70  
               }
      -  70  6
           }
      -  71   -
       
      +  71  12
           }
       72   -
           /**
      +
       
       73   -
            * Parses the command line arguments.
      +
           /**
       74   -
            *
      +
            * Parses the command line arguments.
       75   -
            * @param args the command line arguments
      +
            *
       76   -
            * @return the results of parsing the command line arguments
      +
            * @param args the command line arguments
       77   -
            * @throws ParseException if the arguments are invalid
      +
            * @return the results of parsing the command line arguments
       78   -
            */
      +
            * @throws ParseException if the arguments are invalid
       79   +
            */
      +  80  
           private CommandLine parseArgs(String[] args) throws ParseException {
      -  80  9
               final CommandLineParser parser = new DefaultParser();
      -  81  9
               final Options options = createCommandLineOptions();
      -  82  9
               return parser.parse(options, args);
      -  83   -
           }
      +  81  18
               final CommandLineParser parser = new DefaultParser();
      +  82  18
               final Options options = createCommandLineOptions();
      +  83  18
               return parser.parse(options, args);
       84   -
       
      +
           }
       85   -
           /**
      +
       
       86   -
            * Validates that the command line arguments are valid.
      +
           /**
       87   -
            *
      +
            * Validates that the command line arguments are valid.
       88   -
            * @throws FileNotFoundException if there is a file specified by either the SCAN or CPE command line arguments that does not
      +
            *
       89   -
            * exist.
      +
            * @throws FileNotFoundException if there is a file specified by either the
       90   -
            * @throws ParseException is thrown if there is an exception parsing the command line.
      +
            * SCAN or CPE command line arguments that does not exist.
       91   -
            */
      +
            * @throws ParseException is thrown if there is an exception parsing the
       92   +
            * command line.
      +  93   +
            */
      +  94  
           private void validateArgs() throws FileNotFoundException, ParseException {
      -  93  7
               if (isUpdateOnly() || isRunScan()) {
      -  94  2
                   final String value = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS);
      -  95  2
                   if (value != null) {
      -  96   +  95  14
               if (isUpdateOnly() || isRunScan()) {
      +  96  4
                   final String value = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS);
      +  97  4
                   if (value != null) {
      +  98  
                       try {
      -  97  0
                           final int i = Integer.parseInt(value);
      -  98  0
                           if (i < 0) {
      -  99  0
                               throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0.");
      -  100   +  99  0
                           final int i = Integer.parseInt(value);
      +  100  0
                           if (i < 0) {
      +  101  0
                               throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0.");
      +  102  
                           }
      -  101  0
                       } catch (NumberFormatException ex) {
      -  102  0
                           throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0.");
      -  103  0
                       }
      -  104   +  103  0
                       } catch (NumberFormatException ex) {
      +  104  0
                           throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0.");
      +  105  0
                       }
      +  106  
                   }
      -  105   +  107  
               }
      -  106  7
               if (isRunScan()) {
      -  107  2
                   validatePathExists(getScanFiles(), ARGUMENT.SCAN);
      -  108  1
                   validatePathExists(getReportDirectory(), ARGUMENT.OUT);
      -  109  1
                   if (getPathToMono() != null) {
      -  110  0
                       validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO);
      -  111   +  108  14
               if (isRunScan()) {
      +  109  4
                   validatePathExists(getScanFiles(), ARGUMENT.SCAN);
      +  110  2
                   validatePathExists(getReportDirectory(), ARGUMENT.OUT);
      +  111  2
                   if (getPathToMono() != null) {
      +  112  0
                       validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO);
      +  113  
                   }
      -  112  1
                   if (!line.hasOption(ARGUMENT.APP_NAME) && !line.hasOption(ARGUMENT.PROJECT)) {
      -  113  0
                       throw new ParseException("Missing '" + ARGUMENT.PROJECT + "' argument; the scan cannot be run without the an project name.");
      -  114   +  114  2
                   if (!line.hasOption(ARGUMENT.APP_NAME) && !line.hasOption(ARGUMENT.PROJECT)) {
      +  115  0
                       throw new ParseException("Missing '" + ARGUMENT.PROJECT + "' argument; the scan cannot be run without the an project name.");
      +  116  
                   }
      -  115  1
                   if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
      -  116  0
                       final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
      -  117   +  117  2
                   if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
      +  118  0
                       final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
      +  119  
                       try {
      -  118  0
                           Format.valueOf(format);
      -  119  0
                       } catch (IllegalArgumentException ex) {
      -  120  0
                           final String msg = String.format("An invalid 'format' of '%s' was specified. "
      -  121   +  120  0
                           Format.valueOf(format);
      +  121  0
                       } catch (IllegalArgumentException ex) {
      +  122  0
                           final String msg = String.format("An invalid 'format' of '%s' was specified. "
      +  123  
                                   + "Supported output formats are XML, HTML, VULN, or ALL", format);
      -  122  0
                           throw new ParseException(msg);
      -  123  0
                       }
      -  124   +  124  0
                           throw new ParseException(msg);
      +  125  0
                       }
      +  126  
                   }
      -  125  1
                   if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null)
      -  126  0
                           && (getBaseCve12Url() == null || getBaseCve20Url() == null || getModifiedCve12Url() == null || getModifiedCve20Url() == null)) {
      -  127  0
                       final String msg = "If one of the CVE URLs is specified they must all be specified; please add the missing CVE URL.";
      -  128  0
                       throw new ParseException(msg);
      -  129   -
                   }
      -  130  1
                   if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) {
      +  127  2
                   if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null)
      +  128  0
                           && (getBaseCve12Url() == null || getBaseCve20Url() == null || getModifiedCve12Url() == null || getModifiedCve20Url() == null)) {
      +  129  0
                       final String msg = "If one of the CVE URLs is specified they must all be specified; please add the missing CVE URL.";
      +  130  0
                       throw new ParseException(msg);
       131   -
                       try {
      -  132  0
                           final int i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH));
      -  133  0
                           if (i < 0) {
      -  134  0
                               throw new ParseException("Symbolic Link Depth (symLink) must be greater than zero.");
      -  135   -
                           }
      -  136  0
                       } catch (NumberFormatException ex) {
      -  137  0
                           throw new ParseException("Symbolic Link Depth (symLink) is not a number.");
      -  138  0
                       }
      -  139  
                   }
      -  140   -
               }
      -  141  6
           }
      +  132  2
                   if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) {
      +  133   +
                       try {
      +  134  0
                           final int i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH));
      +  135  0
                           if (i < 0) {
      +  136  0
                               throw new ParseException("Symbolic Link Depth (symLink) must be greater than zero.");
      +  137   +
                           }
      +  138  0
                       } catch (NumberFormatException ex) {
      +  139  0
                           throw new ParseException("Symbolic Link Depth (symLink) is not a number.");
      +  140  0
                       }
      +  141   +
                   }
       142   -
       
      -  143   -
           /**
      -  144   -
            * Validates whether or not the path(s) points at a file that exists; if the path(s) does not point to an existing file a
      -  145   -
            * FileNotFoundException is thrown.
      -  146   -
            *
      -  147   -
            * @param paths the paths to validate if they exists
      -  148   -
            * @param optType the option being validated (e.g. scan, out, etc.)
      -  149   -
            * @throws FileNotFoundException is thrown if one of the paths being validated does not exist.
      -  150   -
            */
      -  151   -
           private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
      -  152  3
               for (String path : paths) {
      -  153  2
                   validatePathExists(path, optType);
      -  154  
               }
      -  155  1
           }
      -  156   +  143  12
           }
      +  144  
       
      -  157   +  145  
           /**
      -  158   -
            * Validates whether or not the path points at a file that exists; if the path does not point to an existing file a
      -  159   -
            * FileNotFoundException is thrown.
      -  160   +  146   +
            * Validates whether or not the path(s) points at a file that exists; if the
      +  147   +
            * path(s) does not point to an existing file a FileNotFoundException is
      +  148   +
            * thrown.
      +  149  
            *
      -  161   -
            * @param path the paths to validate if they exists
      -  162   -
            * @param argumentName the argument being validated (e.g. scan, out, etc.)
      -  163   -
            * @throws FileNotFoundException is thrown if the path being validated does not exist.
      -  164   +  150   +
            * @param paths the paths to validate if they exists
      +  151   +
            * @param optType the option being validated (e.g. scan, out, etc.)
      +  152   +
            * @throws FileNotFoundException is thrown if one of the paths being
      +  153   +
            * validated does not exist.
      +  154  
            */
      +  155   +
           private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
      +  156  6
               for (String path : paths) {
      +  157  4
                   validatePathExists(path, optType);
      +  158   +
               }
      +  159  2
           }
      +  160   +
       
      +  161   +
           /**
      +  162   +
            * Validates whether or not the path points at a file that exists; if the
      +  163   +
            * path does not point to an existing file a FileNotFoundException is
      +  164   +
            * thrown.
       165   +
            *
      +  166   +
            * @param path the paths to validate if they exists
      +  167   +
            * @param argumentName the argument being validated (e.g. scan, out, etc.)
      +  168   +
            * @throws FileNotFoundException is thrown if the path being validated does
      +  169   +
            * not exist.
      +  170   +
            */
      +  171  
           private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
      -  166  3
               if (path == null) {
      -  167  0
                   isValid = false;
      -  168  0
                   final String msg = String.format("Invalid '%s' argument: null", argumentName);
      -  169  0
                   throw new FileNotFoundException(msg);
      -  170  3
               } else if (!path.contains("*") && !path.contains("?")) {
      -  171  3
                   File f = new File(path);
      -  172  3
                   if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) {
      -  173  1
                       final String checkPath = path.toLowerCase();
      -  174  1
                       if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) {
      -  175  0
                           if (f.getParentFile() == null) {
      -  176  0
                               f = new File(".", path);
      -  177   -
                           }
      -  178  0
                           if (!f.getParentFile().isDirectory()) {
      -  179  0
                               isValid = false;
      -  180  0
                               final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
      -  181  0
                               throw new FileNotFoundException(msg);
      -  182   -
                           }
      +  172  6
               if (path == null) {
      +  173  0
                   isValid = false;
      +  174  0
                   final String msg = String.format("Invalid '%s' argument: null", argumentName);
      +  175  0
                   throw new FileNotFoundException(msg);
      +  176  6
               } else if (!path.contains("*") && !path.contains("?")) {
      +  177  6
                   File f = new File(path);
      +  178  6
                   if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) {
      +  179  2
                       final String checkPath = path.toLowerCase();
      +  180  2
                       if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) {
      +  181  0
                           if (f.getParentFile() == null) {
      +  182  0
                               f = new File(".", path);
       183   -
                       }
      -  184  1
                   } else {
      -  185  2
                       if (!f.exists()) {
      -  186  1
                           isValid = false;
      -  187  1
                           final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
      -  188  1
                           throw new FileNotFoundException(msg);
      +
                           }
      +  184  0
                           if (!f.getParentFile().isDirectory()) {
      +  185  0
                               isValid = false;
      +  186  0
                               final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
      +  187  0
                               throw new FileNotFoundException(msg);
      +  188   +
                           }
       189  
                       }
      -  190   +  190  2
                   } else if (!f.exists()) {
      +  191  2
                       isValid = false;
      +  192  2
                       final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
      +  193  2
                       throw new FileNotFoundException(msg);
      +  194  
                   }
      -  191  2
               } else if (path.startsWith("//") || path.startsWith("\\\\")) {
      -  192  0
                   isValid = false;
      -  193  0
                   final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path);
      -  194  0
                   throw new FileNotFoundException(msg);
      -  195   -
               }
      -  196  2
           }
      -  197   -
       
      -  198   -
           /**
      +  195  4
               } else if (path.startsWith("//") || path.startsWith("\\\\")) {
      +  196  0
                   isValid = false;
      +  197  0
                   final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path);
      +  198  0
                   throw new FileNotFoundException(msg);
       199   -
            * Generates an Options collection that is used to parse the command line and to display the help message.
      -  200   -
            *
      +
               }
      +  200  4
           }
       201   -
            * @return the command line options used for parsing the command line
      +
       
       202   -
            */
      -  203   -
           @SuppressWarnings("static-access")
      -  204   -
           private Options createCommandLineOptions() {
      -  205  9
               final Options options = new Options();
      -  206  9
               addStandardOptions(options);
      -  207  9
               addAdvancedOptions(options);
      -  208  9
               addDeprecatedOptions(options);
      -  209  9
               return options;
      -  210   -
           }
      -  211   -
       
      -  212  
           /**
      -  213   -
            * Adds the standard command line options to the given options collection.
      -  214   +  203   +
            * Generates an Options collection that is used to parse the command line
      +  204   +
            * and to display the help message.
      +  205  
            *
      -  215   -
            * @param options a collection of command line arguments
      -  216   -
            * @throws IllegalArgumentException thrown if there is an exception
      -  217   +  206   +
            * @return the command line options used for parsing the command line
      +  207  
            */
      -  218   +  208  
           @SuppressWarnings("static-access")
      +  209   +
           private Options createCommandLineOptions() {
      +  210  18
               final Options options = new Options();
      +  211  18
               addStandardOptions(options);
      +  212  18
               addAdvancedOptions(options);
      +  213  18
               addDeprecatedOptions(options);
      +  214  18
               return options;
      +  215   +
           }
      +  216   +
       
      +  217   +
           /**
      +  218   +
            * Adds the standard command line options to the given options collection.
       219   -
           private void addStandardOptions(final Options options) throws IllegalArgumentException {
      -  220  11
               final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
      +
            *
      +  220   +
            * @param options a collection of command line arguments
       221   -
                       "Print this message.");
      +
            * @throws IllegalArgumentException thrown if there is an exception
       222   -
       
      -  223  11
               final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP)
      -  224  11
                       .desc("Print the advanced help message.").build();
      -  225   -
       
      -  226  11
               final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
      +
            */
      +  223   +
           @SuppressWarnings("static-access")
      +  224   +
           private void addStandardOptions(final Options options) throws IllegalArgumentException {
      +  225  22
               final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
      +  226   +
                       "Print this message.");
       227   -
                       false, "Print the version information.");
      -  228  
       
      -  229  11
               final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
      +  228  22
               final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP)
      +  229  22
                       .desc("Print the advanced help message.").build();
       230   -
                       false, "Disables the automatic updating of the CPE data.");
      -  231  
       
      -  232  11
               final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT)
      -  233  11
                       .desc("The name of the project being scanned. This is a required argument.")
      -  234  11
                       .build();
      +  231  22
               final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
      +  232   +
                       false, "Print the version information.");
      +  233   +
       
      +  234  22
               final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
       235   +
                       false, "Disables the automatic updating of the CPE data.");
      +  236  
       
      -  236  11
               final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN)
      -  237  11
                       .desc("The path to scan - this option can be specified multiple times. Ant style"
      -  238   -
                               + " paths are supported (e.g. path/**/*.jar).")
      -  239  11
                       .build();
      +  237  22
               final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT)
      +  238  22
                       .desc("The name of the project being scanned. This is a required argument.")
      +  239  22
                       .build();
       240  
       
      -  241  11
               final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE)
      -  242  11
                       .desc("Specify and exclusion pattern. This option can be specified multiple times"
      +  241  22
               final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN)
      +  242  22
                       .desc("The path to scan - this option can be specified multiple times. Ant style"
       243   -
                               + " and it accepts Ant style excludsions.")
      -  244  11
                       .build();
      +
                               + " paths are supported (e.g. path/**/*.jar).")
      +  244  22
                       .build();
       245  
       
      -  246  11
               final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP)
      -  247  11
                       .desc("A property file to load.")
      -  248  11
                       .build();
      -  249   +  246  22
               final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE)
      +  247  22
                       .desc("Specify and exclusion pattern. This option can be specified multiple times"
      +  248   +
                               + " and it accepts Ant style excludsions.")
      +  249  22
                       .build();
      +  250  
       
      -  250  11
               final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT)
      -  251  11
                       .desc("The folder to write reports to. This defaults to the current directory. "
      -  252   -
                               + "It is possible to set this to a specific file name if the format argument is not set to ALL.")
      -  253  11
                       .build();
      +  251  22
               final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP)
      +  252  22
                       .desc("A property file to load.")
      +  253  22
                       .build();
       254  
       
      -  255  11
               final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT)
      -  256  11
                       .desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
      -  257  11
                       .build();
      -  258   +  255  22
               final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT)
      +  256  22
                       .desc("The folder to write reports to. This defaults to the current directory. "
      +  257   +
                               + "It is possible to set this to a specific file name if the format argument is not set to ALL.")
      +  258  22
                       .build();
      +  259  
       
      -  259  11
               final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG)
      -  260  11
                       .desc("The file path to write verbose logging information.")
      -  261  11
                       .build();
      -  262   +  260  22
               final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT)
      +  261  22
                       .desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
      +  262  22
                       .build();
      +  263  
       
      -  263  11
               final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH)
      -  264  11
                       .desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.")
      -  265  11
                       .build();
      -  266   +  264  22
               final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG)
      +  265  22
                       .desc("The file path to write verbose logging information.")
      +  266  22
                       .build();
      +  267  
       
      -  267  11
               final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE)
      -  268  11
                       .desc("The file path to the suppression XML file.")
      -  269  11
                       .build();
      -  270   -
       
      -  271  11
               final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS)
      -  272  11
                       .desc("The number of hours to wait before checking for new updates from the NVD.")
      -  273  11
                       .build();
      -  274   +  268  22
               final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH)
      +  269  22
                       .desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.")
      +  270  22
                       .build();
      +  271  
       
      +  272  22
               final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE)
      +  273  22
                       .desc("The file path to the suppression XML file.")
      +  274  22
                       .build();
       275   +
       
      +  276  22
               final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS)
      +  277  22
                       .desc("The number of hours to wait before checking for new updates from the NVD.")
      +  278  22
                       .build();
      +  279   +
       
      +  280  22
               final Option experimentalEnabled = Option.builder().longOpt(ARGUMENT.EXPERIMENTAL)
      +  281  22
                       .desc("Enables the experimental analzers.")
      +  282  22
                       .build();
      +  283   +
       
      +  284  
               //This is an option group because it can be specified more then once.
      -  276  11
               final OptionGroup og = new OptionGroup();
      -  277  11
               og.addOption(path);
      -  278   +  285  22
               final OptionGroup og = new OptionGroup();
      +  286  22
               og.addOption(path);
      +  287  
       
      -  279  11
               final OptionGroup exog = new OptionGroup();
      -  280  11
               exog.addOption(excludes);
      -  281   +  288  22
               final OptionGroup exog = new OptionGroup();
      +  289  22
               exog.addOption(excludes);
      +  290  
       
      -  282  11
               options.addOptionGroup(og)
      -  283  11
                       .addOptionGroup(exog)
      -  284  11
                       .addOption(projectName)
      -  285  11
                       .addOption(out)
      -  286  11
                       .addOption(outputFormat)
      -  287  11
                       .addOption(version)
      -  288  11
                       .addOption(help)
      -  289  11
                       .addOption(advancedHelp)
      -  290  11
                       .addOption(noUpdate)
      -  291  11
                       .addOption(symLinkDepth)
      -  292  11
                       .addOption(props)
      -  293  11
                       .addOption(verboseLog)
      -  294  11
                       .addOption(suppressionFile)
      -  295  11
                       .addOption(cveValidForHours);
      -  296  11
           }
      -  297   -
       
      -  298   -
           /**
      -  299   -
            * Adds the advanced command line options to the given options collection. These are split out for purposes of being able to
      -  300   -
            * display two different help messages.
      -  301   -
            *
      -  302   -
            * @param options a collection of command line arguments
      -  303   -
            * @throws IllegalArgumentException thrown if there is an exception
      -  304   -
            */
      -  305   -
           @SuppressWarnings("static-access")
      -  306   -
           private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
      +  291  22
               options.addOptionGroup(og)
      +  292  22
                       .addOptionGroup(exog)
      +  293  22
                       .addOption(projectName)
      +  294  22
                       .addOption(out)
      +  295  22
                       .addOption(outputFormat)
      +  296  22
                       .addOption(version)
      +  297  22
                       .addOption(help)
      +  298  22
                       .addOption(advancedHelp)
      +  299  22
                       .addOption(noUpdate)
      +  300  22
                       .addOption(symLinkDepth)
      +  301  22
                       .addOption(props)
      +  302  22
                       .addOption(verboseLog)
      +  303  22
                       .addOption(suppressionFile)
      +  304  22
                       .addOption(cveValidForHours)
      +  305  22
                       .addOption(experimentalEnabled);
      +  306  22
           }
       307  
       
      -  308  9
               final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12)
      -  309  9
                       .desc("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ")
      -  310  9
                       .build();
      +  308   +
           /**
      +  309   +
            * Adds the advanced command line options to the given options collection.
      +  310   +
            * These are split out for purposes of being able to display two different
       311   -
       
      -  312  9
               final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20)
      -  313  9
                       .desc("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.")
      -  314  9
                       .build();
      +
            * help messages.
      +  312   +
            *
      +  313   +
            * @param options a collection of command line arguments
      +  314   +
            * @throws IllegalArgumentException thrown if there is an exception
       315   +
            */
      +  316   +
           @SuppressWarnings("static-access")
      +  317   +
           private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
      +  318  
       
      -  316  9
               final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12)
      -  317  9
                       .desc("URL for the modified CVE 1.2.")
      -  318  9
                       .build();
      -  319   +  319  18
               final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12)
      +  320  18
                       .desc("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ")
      +  321  18
                       .build();
      +  322  
       
      -  320  9
               final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20)
      -  321  9
                       .desc("URL for the modified CVE 2.0.")
      -  322  9
                       .build();
      -  323   -
       
      -  324  9
               final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY)
      -  325  9
                       .desc("Only update the local NVD data cache; no scan will be executed.").build();
      +  323  18
               final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20)
      +  324  18
                       .desc("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.")
      +  325  18
                       .build();
       326  
       
      -  327  9
               final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY)
      -  328  9
                       .desc("The location of the H2 Database file. This option should generally not be set.")
      -  329  9
                       .build();
      +  327  18
               final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12)
      +  328  18
                       .desc("URL for the modified CVE 1.2.")
      +  329  18
                       .build();
       330  
       
      -  331  9
               final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL)
      -  332  9
                       .desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). "
      -  333  9
                               + "If not set the Nexus Analyzer will be disabled.").build();
      +  331  18
               final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20)
      +  332  18
                       .desc("URL for the modified CVE 2.0.")
      +  333  18
                       .build();
       334  
       
      -  335  9
               final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY)
      -  336  9
                       .desc("Whether or not the configured proxy should be used when connecting to Nexus.")
      -  337  9
                       .build();
      -  338   +  335  18
               final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY)
      +  336  18
                       .desc("Only update the local NVD data cache; no scan will be executed.").build();
      +  337  
       
      -  339  9
               final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg()
      -  340  9
                       .longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
      -  341  9
                       .desc("A comma separated list of additional extensions to be scanned as ZIP files "
      -  342  9
                               + "(ZIP, EAR, WAR are already treated as zip files)").build();
      -  343   +  338  18
               final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY)
      +  339  18
                       .desc("The location of the H2 Database file. This option should generally not be set.")
      +  340  18
                       .build();
      +  341  
       
      -  344  9
               final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO)
      -  345  9
                       .desc("The path to Mono for .NET Assembly analysis on non-windows systems.")
      -  346  9
                       .build();
      -  347   +  342  18
               final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL)
      +  343  18
                       .desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). "
      +  344  18
                               + "If not set the Nexus Analyzer will be disabled.").build();
      +  345  
       
      -  348  9
               final Option pathToBundleAudit = Option.builder().argName("path").hasArg()
      -  349  9
                       .longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT)
      -  350  9
                       .desc("The path to bundle-audit for Gem bundle analysis.").build();
      -  351   +  346  18
               final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY)
      +  347  18
                       .desc("Whether or not the configured proxy should be used when connecting to Nexus.")
      +  348  18
                       .build();
      +  349  
       
      -  352  9
               final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg()
      -  353  9
                       .longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.")
      -  354  9
                       .build();
      -  355   +  350  18
               final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg()
      +  351  18
                       .longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
      +  352  18
                       .desc("A comma separated list of additional extensions to be scanned as ZIP files "
      +  353  18
                               + "(ZIP, EAR, WAR are already treated as zip files)").build();
      +  354  
       
      -  356  9
               final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER)
      -  357  9
                       .desc("The proxy server to use when downloading resources.").build();
      +  355  18
               final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO)
      +  356  18
                       .desc("The path to Mono for .NET Assembly analysis on non-windows systems.")
      +  357  18
                       .build();
       358  
       
      -  359  9
               final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT)
      -  360  9
                       .desc("The proxy port to use when downloading resources.").build();
      -  361   +  359  18
               final Option pathToBundleAudit = Option.builder().argName("path").hasArg()
      +  360  18
                       .longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT)
      +  361  18
                       .desc("The path to bundle-audit for Gem bundle analysis.").build();
      +  362  
       
      -  362  9
               final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME)
      -  363  9
                       .desc("The proxy username to use when downloading resources.").build();
      -  364   +  363  18
               final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg()
      +  364  18
                       .longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.")
      +  365  18
                       .build();
      +  366  
       
      -  365  9
               final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD)
      -  366  9
                       .desc("The proxy password to use when downloading resources.").build();
      -  367   +  367  18
               final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER)
      +  368  18
                       .desc("The proxy server to use when downloading resources.").build();
      +  369  
       
      -  368  9
               final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING)
      -  369  9
                       .desc("The connection string to the database.").build();
      -  370   +  370  18
               final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT)
      +  371  18
                       .desc("The proxy port to use when downloading resources.").build();
      +  372  
       
      -  371  9
               final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME)
      -  372  9
                       .desc("The username used to connect to the database.").build();
      -  373   +  373  18
               final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME)
      +  374  18
                       .desc("The proxy username to use when downloading resources.").build();
      +  375  
       
      -  374  9
               final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD)
      -  375  9
                       .desc("The password for connecting to the database.").build();
      -  376   +  376  18
               final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD)
      +  377  18
                       .desc("The proxy password to use when downloading resources.").build();
      +  378  
       
      -  377  9
               final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER)
      -  378  9
                       .desc("The database driver name.").build();
      -  379   +  379  18
               final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING)
      +  380  18
                       .desc("The connection string to the database.").build();
      +  381  
       
      -  380  9
               final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH)
      -  381  9
                       .desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
      -  382  9
                       .build();
      -  383   +  382  18
               final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME)
      +  383  18
                       .desc("The username used to connect to the database.").build();
      +  384  
       
      -  384  9
               final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR)
      -  385  9
                       .desc("Disable the Jar Analyzer.").build();
      -  386   +  385  18
               final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD)
      +  386  18
                       .desc("The password for connecting to the database.").build();
      +  387  
       
      -  387  9
               final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE)
      -  388  9
                       .desc("Disable the Archive Analyzer.").build();
      -  389   +  388  18
               final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER)
      +  389  18
                       .desc("The database driver name.").build();
      +  390  
       
      -  390  9
               final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC)
      -  391  9
                       .desc("Disable the Nuspec Analyzer.").build();
      -  392   +  391  18
               final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH)
      +  392  18
                       .desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
      +  393  18
                       .build();
      +  394  
       
      -  393  9
               final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY)
      -  394  9
                       .desc("Disable the .NET Assembly Analyzer.").build();
      -  395   +  395  18
               final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR)
      +  396  18
                       .desc("Disable the Jar Analyzer.").build();
      +  397  
       
      -  396  9
               final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST)
      -  397  9
                       .desc("Disable the Python Distribution Analyzer.").build();
      -  398   +  398  18
               final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE)
      +  399  18
                       .desc("Disable the Archive Analyzer.").build();
      +  400  
       
      -  399  9
               final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG)
      -  400  9
                       .desc("Disable the Python Package Analyzer.").build();
      -  401   +  401  18
               final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC)
      +  402  18
                       .desc("Disable the Nuspec Analyzer.").build();
      +  403  
       
      -  402  9
               final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER)
      -  403  9
                       .desc("Disable the PHP Composer Analyzer.").build();
      -  404   +  404  18
               final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY)
      +  405  18
                       .desc("Disable the .NET Assembly Analyzer.").build();
      +  406  
       
      -  405  9
               final Option disableAutoconfAnalyzer = Option.builder()
      -  406  9
                       .longOpt(ARGUMENT.DISABLE_AUTOCONF)
      -  407  9
                       .desc("Disable the Autoconf Analyzer.").build();
      -  408   +  407  18
               final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST)
      +  408  18
                       .desc("Disable the Python Distribution Analyzer.").build();
      +  409  
       
      -  409  9
               final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL)
      -  410  9
                       .desc("Disable the OpenSSL Analyzer.").build();
      -  411  9
               final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE)
      -  412  9
                       .desc("Disable the Cmake Analyzer.").build();
      -  413   +  410  18
               final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG)
      +  411  18
                       .desc("Disable the Python Package Analyzer.").build();
      +  412  
       
      -  414  9
               final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL)
      -  415  9
                       .desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable "
      -  416  9
                               + "the Nexus Analyzer.").build();
      -  417   +  413  18
               final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER)
      +  414  18
                       .desc("Disable the PHP Composer Analyzer.").build();
      +  415  
       
      -  418  9
               final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS)
      -  419  9
                       .desc("Disable the Nexus Analyzer.").build();
      -  420   +  416  18
               final Option disableAutoconfAnalyzer = Option.builder()
      +  417  18
                       .longOpt(ARGUMENT.DISABLE_AUTOCONF)
      +  418  18
                       .desc("Disable the Autoconf Analyzer.").build();
      +  419  
       
      -  421  9
               final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD)
      -  422  9
                       .desc("Purges the local NVD data cache")
      -  423  9
                       .build();
      +  420  18
               final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL)
      +  421  18
                       .desc("Disable the OpenSSL Analyzer.").build();
      +  422  18
               final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE)
      +  423  18
                       .desc("Disable the Cmake Analyzer.").build();
       424  
       
      -  425  9
               options.addOption(updateOnly)
      -  426  9
                       .addOption(cve12Base)
      -  427  9
                       .addOption(cve20Base)
      -  428  9
                       .addOption(cve12Modified)
      -  429  9
                       .addOption(cve20Modified)
      -  430  9
                       .addOption(proxyPort)
      -  431  9
                       .addOption(proxyServer)
      -  432  9
                       .addOption(proxyUsername)
      -  433  9
                       .addOption(proxyPassword)
      -  434  9
                       .addOption(connectionTimeout)
      -  435  9
                       .addOption(connectionString)
      -  436  9
                       .addOption(dbUser)
      -  437  9
                       .addOption(data)
      -  438  9
                       .addOption(dbPassword)
      -  439  9
                       .addOption(dbDriver)
      -  440  9
                       .addOption(dbDriverPath)
      -  441  9
                       .addOption(disableJarAnalyzer)
      -  442  9
                       .addOption(disableArchiveAnalyzer)
      -  443  9
                       .addOption(disableAssemblyAnalyzer)
      -  444  9
                       .addOption(pathToBundleAudit)
      -  445  9
                       .addOption(disablePythonDistributionAnalyzer)
      -  446  9
                       .addOption(disableCmakeAnalyzer)
      -  447  9
                       .addOption(disablePythonPackageAnalyzer)
      -  448  18
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS)
      -  449  9
                               .desc("Disable the Ruby Gemspec Analyzer.").build())
      -  450  18
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT)
      -  451  9
                               .desc("Disable the Ruby Bundler-Audit Analyzer.").build())
      -  452  9
                       .addOption(disableAutoconfAnalyzer)
      -  453  9
                       .addOption(disableComposerAnalyzer)
      -  454  9
                       .addOption(disableOpenSSLAnalyzer)
      -  455  9
                       .addOption(disableNuspecAnalyzer)
      -  456  9
                       .addOption(disableCentralAnalyzer)
      -  457  9
                       .addOption(disableNexusAnalyzer)
      -  458  18
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS)
      -  459  9
                               .desc("Disable the Node.js Package Analyzer.").build())
      -  460  9
                       .addOption(nexusUrl)
      -  461  9
                       .addOption(nexusUsesProxy)
      -  462  9
                       .addOption(additionalZipExtensions)
      -  463  9
                       .addOption(pathToMono)
      -  464  9
                       .addOption(pathToBundleAudit)
      -  465  9
                       .addOption(purge);
      -  466  9
           }
      -  467   +  425  18
               final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL)
      +  426  18
                       .desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable "
      +  427  18
                               + "the Nexus Analyzer.").build();
      +  428  
       
      -  468   +  429  18
               final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS)
      +  430  18
                       .desc("Disable the Nexus Analyzer.").build();
      +  431   +
       
      +  432  18
               final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD)
      +  433  18
                       .desc("Purges the local NVD data cache")
      +  434  18
                       .build();
      +  435   +
       
      +  436  18
               options.addOption(updateOnly)
      +  437  18
                       .addOption(cve12Base)
      +  438  18
                       .addOption(cve20Base)
      +  439  18
                       .addOption(cve12Modified)
      +  440  18
                       .addOption(cve20Modified)
      +  441  18
                       .addOption(proxyPort)
      +  442  18
                       .addOption(proxyServer)
      +  443  18
                       .addOption(proxyUsername)
      +  444  18
                       .addOption(proxyPassword)
      +  445  18
                       .addOption(connectionTimeout)
      +  446  18
                       .addOption(connectionString)
      +  447  18
                       .addOption(dbUser)
      +  448  18
                       .addOption(data)
      +  449  18
                       .addOption(dbPassword)
      +  450  18
                       .addOption(dbDriver)
      +  451  18
                       .addOption(dbDriverPath)
      +  452  18
                       .addOption(disableJarAnalyzer)
      +  453  18
                       .addOption(disableArchiveAnalyzer)
      +  454  18
                       .addOption(disableAssemblyAnalyzer)
      +  455  18
                       .addOption(pathToBundleAudit)
      +  456  18
                       .addOption(disablePythonDistributionAnalyzer)
      +  457  18
                       .addOption(disableCmakeAnalyzer)
      +  458  18
                       .addOption(disablePythonPackageAnalyzer)
      +  459  36
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS)
      +  460  18
                               .desc("Disable the Ruby Gemspec Analyzer.").build())
      +  461  36
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT)
      +  462  18
                               .desc("Disable the Ruby Bundler-Audit Analyzer.").build())
      +  463  18
                       .addOption(disableAutoconfAnalyzer)
      +  464  18
                       .addOption(disableComposerAnalyzer)
      +  465  18
                       .addOption(disableOpenSSLAnalyzer)
      +  466  18
                       .addOption(disableNuspecAnalyzer)
      +  467  18
                       .addOption(disableCentralAnalyzer)
      +  468  18
                       .addOption(disableNexusAnalyzer)
      +  469  36
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS)
      +  470  18
                               .desc("Disable the Node.js Package Analyzer.").build())
      +  471  18
                       .addOption(nexusUrl)
      +  472  18
                       .addOption(nexusUsesProxy)
      +  473  18
                       .addOption(additionalZipExtensions)
      +  474  18
                       .addOption(pathToMono)
      +  475  18
                       .addOption(pathToBundleAudit)
      +  476  18
                       .addOption(purge);
      +  477  18
           }
      +  478   +
       
      +  479  
           /**
      -  469   -
            * Adds the deprecated command line options to the given options collection. These are split out for purposes of not including
      -  470   -
            * them in the help message. We need to add the deprecated options so as not to break existing scripts.
      -  471   -
            *
      -  472   -
            * @param options a collection of command line arguments
      -  473   -
            * @throws IllegalArgumentException thrown if there is an exception
      -  474   -
            */
      -  475   -
           @SuppressWarnings({"static-access", "deprecation"})
      -  476   -
           private void addDeprecatedOptions(final Options options) throws IllegalArgumentException {
      -  477   -
       
      -  478  9
               final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL)
      -  479  9
                       .desc("The proxy url argument is deprecated, use proxyserver instead.")
      -  480  9
                       .build();
      -  481  9
               final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME)
      -  482  9
                       .desc("The name of the project being scanned.")
      -  483  9
                       .build();
      +  480   +
            * Adds the deprecated command line options to the given options collection.
      +  481   +
            * These are split out for purposes of not including them in the help
      +  482   +
            * message. We need to add the deprecated options so as not to break
      +  483   +
            * existing scripts.
       484   -
       
      -  485  9
               options.addOption(proxyServer);
      -  486  9
               options.addOption(appName);
      -  487  9
           }
      -  488   -
       
      -  489   -
           /**
      -  490   -
            * Determines if the 'version' command line argument was passed in.
      -  491  
            *
      -  492   -
            * @return whether or not the 'version' command line argument was passed in
      -  493   +  485   +
            * @param options a collection of command line arguments
      +  486   +
            * @throws IllegalArgumentException thrown if there is an exception
      +  487  
            */
      -  494   -
           public boolean isGetVersion() {
      -  495  7
               return (line != null) && line.hasOption(ARGUMENT.VERSION);
      -  496   -
           }
      +  488   +
           @SuppressWarnings({"static-access", "deprecation"})
      +  489   +
           private void addDeprecatedOptions(final Options options) throws IllegalArgumentException {
      +  490   +
       
      +  491  18
               final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL)
      +  492  18
                       .desc("The proxy url argument is deprecated, use proxyserver instead.")
      +  493  18
                       .build();
      +  494  18
               final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME)
      +  495  18
                       .desc("The name of the project being scanned.")
      +  496  18
                       .build();
       497  
       
      -  498   -
           /**
      -  499   -
            * Determines if the 'help' command line argument was passed in.
      -  500   -
            *
      +  498  18
               options.addOption(proxyServer);
      +  499  18
               options.addOption(appName);
      +  500  18
           }
       501   -
            * @return whether or not the 'help' command line argument was passed in
      +
       
       502   -
            */
      +
           /**
       503   -
           public boolean isGetHelp() {
      -  504  7
               return (line != null) && line.hasOption(ARGUMENT.HELP);
      +
            * Determines if the 'version' command line argument was passed in.
      +  504   +
            *
       505   -
           }
      +
            * @return whether or not the 'version' command line argument was passed in
       506   -
       
      +
            */
       507   -
           /**
      -  508   -
            * Determines if the 'scan' command line argument was passed in.
      +
           public boolean isGetVersion() {
      +  508  14
               return (line != null) && line.hasOption(ARGUMENT.VERSION);
       509   -
            *
      +
           }
       510   -
            * @return whether or not the 'scan' command line argument was passed in
      +
       
       511   -
            */
      +
           /**
       512   -
           public boolean isRunScan() {
      -  513  21
               return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
      +
            * Determines if the 'help' command line argument was passed in.
      +  513   +
            *
       514   -
           }
      +
            * @return whether or not the 'help' command line argument was passed in
       515   -
       
      +
            */
       516   -
           /**
      -  517   -
            * Returns the symbolic link depth (how deeply symbolic links will be followed).
      +
           public boolean isGetHelp() {
      +  517  14
               return (line != null) && line.hasOption(ARGUMENT.HELP);
       518   -
            *
      +
           }
       519   -
            * @return the symbolic link depth
      +
       
       520   -
            */
      +
           /**
       521   -
           public int getSymLinkDepth() {
      -  522  0
               int value = 0;
      +
            * Determines if the 'scan' command line argument was passed in.
      +  522   +
            *
       523   -
               try {
      -  524  0
                   value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0"));
      -  525  0
                   if (value < 0) {
      -  526  0
                       value = 0;
      +
            * @return whether or not the 'scan' command line argument was passed in
      +  524   +
            */
      +  525   +
           public boolean isRunScan() {
      +  526  42
               return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
       527   -
                   }
      -  528  0
               } catch (NumberFormatException ex) {
      -  529  0
                   LOGGER.debug("Symbolic link was not a number");
      -  530  0
               }
      -  531  0
               return value;
      +
           }
      +  528   +
       
      +  529   +
           /**
      +  530   +
            * Returns the symbolic link depth (how deeply symbolic links will be
      +  531   +
            * followed).
       532   -
           }
      +
            *
       533   -
       
      +
            * @return the symbolic link depth
       534   -
           /**
      +
            */
       535   -
            * Returns true if the disableJar command line argument was specified.
      -  536   -
            *
      +
           public int getSymLinkDepth() {
      +  536  0
               int value = 0;
       537   -
            * @return true if the disableJar command line argument was specified; otherwise false
      -  538   -
            */
      -  539   -
           public boolean isJarDisabled() {
      -  540  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR);
      +
               try {
      +  538  0
                   value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0"));
      +  539  0
                   if (value < 0) {
      +  540  0
                       value = 0;
       541   -
           }
      -  542   -
       
      -  543   -
           /**
      -  544   -
            * Returns true if the disableArchive command line argument was specified.
      -  545   -
            *
      +
                   }
      +  542  0
               } catch (NumberFormatException ex) {
      +  543  0
                   LOGGER.debug("Symbolic link was not a number");
      +  544  0
               }
      +  545  0
               return value;
       546   -
            * @return true if the disableArchive command line argument was specified; otherwise false
      +
           }
       547   -
            */
      +
       
       548   -
           public boolean isArchiveDisabled() {
      -  549  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE);
      +
           /**
      +  549   +
            * Returns true if the disableJar command line argument was specified.
       550   -
           }
      +
            *
       551   -
       
      +
            * @return true if the disableJar command line argument was specified;
       552   -
           /**
      +
            * otherwise false
       553   -
            * Returns true if the disableNuspec command line argument was specified.
      +
            */
       554   -
            *
      -  555   -
            * @return true if the disableNuspec command line argument was specified; otherwise false
      +
           public boolean isJarDisabled() {
      +  555  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR);
       556   -
            */
      +
           }
       557   -
           public boolean isNuspecDisabled() {
      -  558  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC);
      +
       
      +  558   +
           /**
       559   -
           }
      +
            * Returns true if the disableArchive command line argument was specified.
       560   -
       
      +
            *
       561   -
           /**
      +
            * @return true if the disableArchive command line argument was specified;
       562   -
            * Returns true if the disableAssembly command line argument was specified.
      +
            * otherwise false
       563   -
            *
      +
            */
       564   -
            * @return true if the disableAssembly command line argument was specified; otherwise false
      -  565   -
            */
      +
           public boolean isArchiveDisabled() {
      +  565  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE);
       566   -
           public boolean isAssemblyDisabled() {
      -  567  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
      +
           }
      +  567   +
       
       568   -
           }
      +
           /**
       569   -
       
      +
            * Returns true if the disableNuspec command line argument was specified.
       570   -
           /**
      +
            *
       571   -
            * Returns true if the disableBundleAudit command line argument was specified.
      +
            * @return true if the disableNuspec command line argument was specified;
       572   -
            *
      +
            * otherwise false
       573   -
            * @return true if the disableBundleAudit command line argument was specified; otherwise false
      -  574  
            */
      -  575   -
           public boolean isBundleAuditDisabled() {
      -  576  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT);
      -  577   +  574   +
           public boolean isNuspecDisabled() {
      +  575  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC);
      +  576  
           }
      -  578   +  577  
       
      -  579   +  578  
           /**
      +  579   +
            * Returns true if the disableAssembly command line argument was specified.
       580   -
            * Returns true if the disablePyDist command line argument was specified.
      -  581  
            *
      +  581   +
            * @return true if the disableAssembly command line argument was specified;
       582   -
            * @return true if the disablePyDist command line argument was specified; otherwise false
      +
            * otherwise false
       583  
            */
       584   -
           public boolean isPythonDistributionDisabled() {
      -  585  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST);
      +
           public boolean isAssemblyDisabled() {
      +  585  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
       586  
           }
       587   @@ -911,152 +910,153 @@  588  
           /**
       589   -
            * Returns true if the disablePyPkg command line argument was specified.
      +
            * Returns true if the disableBundleAudit command line argument was
       590   -
            *
      +
            * specified.
       591   -
            * @return true if the disablePyPkg command line argument was specified; otherwise false
      +
            *
       592   -
            */
      +
            * @return true if the disableBundleAudit command line argument was
       593   -
           public boolean isPythonPackageDisabled() {
      -  594  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG);
      +
            * specified; otherwise false
      +  594   +
            */
       595   -
           }
      -  596   -
       
      +
           public boolean isBundleAuditDisabled() {
      +  596  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT);
       597   -
           /**
      +
           }
       598   -
            * Returns whether the Ruby gemspec analyzer is disabled.
      +
       
       599   -
            *
      +
           /**
       600   -
            * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line argument was specified; otherwise false
      +
            * Returns true if the disablePyDist command line argument was specified.
       601   -
            */
      +
            *
       602   -
           public boolean isRubyGemspecDisabled() {
      -  603  0
               return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS);
      +
            * @return true if the disablePyDist command line argument was specified;
      +  603   +
            * otherwise false
       604   -
           }
      +
            */
       605   -
       
      -  606   -
           /**
      +
           public boolean isPythonDistributionDisabled() {
      +  606  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST);
       607   -
            * Returns true if the disableCmake command line argument was specified.
      +
           }
       608   -
            *
      +
       
       609   -
            * @return true if the disableCmake command line argument was specified; otherwise false
      +
           /**
       610   -
            */
      +
            * Returns true if the disablePyPkg command line argument was specified.
       611   -
           public boolean isCmakeDisabled() {
      -  612  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE);
      +
            *
      +  612   +
            * @return true if the disablePyPkg command line argument was specified;
       613   -
           }
      +
            * otherwise false
       614   -
       
      +
            */
       615   -
           /**
      -  616   -
            * Returns true if the disableAutoconf command line argument was specified.
      +
           public boolean isPythonPackageDisabled() {
      +  616  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG);
       617   -
            *
      +
           }
       618   -
            * @return true if the disableAutoconf command line argument was specified; otherwise false
      +
       
       619   -
            */
      +
           /**
       620   -
           public boolean isAutoconfDisabled() {
      -  621  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF);
      +
            * Returns whether the Ruby gemspec analyzer is disabled.
      +  621   +
            *
       622   -
           }
      +
            * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line
       623   -
       
      +
            * argument was specified; otherwise false
       624   -
           /**
      +
            */
       625   -
            * Returns true if the disableComposer command line argument was specified.
      -  626   -
            *
      +
           public boolean isRubyGemspecDisabled() {
      +  626  0
               return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS);
       627   -
            * @return true if the disableComposer command line argument was specified; otherwise false
      +
           }
       628   -
            */
      +
       
       629   -
           public boolean isComposerDisabled() {
      -  630  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER);
      +
           /**
      +  630   +
            * Returns true if the disableCmake command line argument was specified.
       631   -
           }
      +
            *
       632   -
       
      +
            * @return true if the disableCmake command line argument was specified;
       633   -
           /**
      +
            * otherwise false
       634   -
            * Returns true if the disableNexus command line argument was specified.
      +
            */
       635   -
            *
      -  636   -
            * @return true if the disableNexus command line argument was specified; otherwise false
      +
           public boolean isCmakeDisabled() {
      +  636  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE);
       637   -
            */
      +
           }
       638   -
           public boolean isNexusDisabled() {
      -  639  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS);
      +
       
      +  639   +
           /**
       640   -
           }
      +
            * Returns true if the disableAutoconf command line argument was specified.
       641   -
       
      +
            *
       642   -
           /**
      +
            * @return true if the disableAutoconf command line argument was specified;
       643   -
            * Returns true if the disableOpenSSL command line argument was specified.
      +
            * otherwise false
       644   -
            *
      +
            */
       645   -
            * @return true if the disableOpenSSL command line argument was specified; otherwise false
      -  646   -
            */
      +
           public boolean isAutoconfDisabled() {
      +  646  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF);
       647   -
           public boolean isOpenSSLDisabled() {
      -  648  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL);
      +
           }
      +  648   +
       
       649   -
           }
      +
           /**
       650   -
       
      +
            * Returns true if the disableComposer command line argument was specified.
       651   -
           /**
      +
            *
       652   -
            * Returns true if the disableNodeJS command line argument was specified.
      +
            * @return true if the disableComposer command line argument was specified;
       653   -
            *
      +
            * otherwise false
       654   -
            * @return true if the disableNodeJS command line argument was specified; otherwise false
      -  655  
            */
      -  656   -
           public boolean isNodeJsDisabled() {
      -  657  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS);
      -  658   +  655   +
           public boolean isComposerDisabled() {
      +  656  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER);
      +  657  
           }
      -  659   +  658  
       
      -  660   +  659  
           /**
      +  660   +
            * Returns true if the disableNexus command line argument was specified.
       661   -
            * Returns true if the disableCentral command line argument was specified.
      -  662  
            *
      +  662   +
            * @return true if the disableNexus command line argument was specified;
       663   -
            * @return true if the disableCentral command line argument was specified; otherwise false
      +
            * otherwise false
       664  
            */
       665   -
           public boolean isCentralDisabled() {
      -  666  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL);
      +
           public boolean isNexusDisabled() {
      +  666  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS);
       667  
           }
       668   @@ -1064,1203 +1064,1373 @@  669  
           /**
       670   -
            * Returns the url to the nexus server if one was specified.
      +
            * Returns true if the disableOpenSSL command line argument was specified.
       671  
            *
       672   -
            * @return the url to the nexus server; if none was specified this will return null;
      +
            * @return true if the disableOpenSSL command line argument was specified;
       673   -
            */
      +
            * otherwise false
       674   -
           public String getNexusUrl() {
      -  675  0
               if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) {
      -  676  0
                   return null;
      +
            */
      +  675   +
           public boolean isOpenSSLDisabled() {
      +  676  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL);
       677   -
               } else {
      -  678  0
                   return line.getOptionValue(ARGUMENT.NEXUS_URL);
      +
           }
      +  678   +
       
       679   -
               }
      +
           /**
       680   -
           }
      +
            * Returns true if the disableNodeJS command line argument was specified.
       681   -
       
      -  682   -
           /**
      -  683   -
            * Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is returned.
      -  684  
            *
      +  682   +
            * @return true if the disableNodeJS command line argument was specified;
      +  683   +
            * otherwise false
      +  684   +
            */
       685   -
            * @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false
      -  686   -
            */
      +
           public boolean isNodeJsDisabled() {
      +  686  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS);
       687   -
           public boolean isNexusUsesProxy() {
      -  688   -
               // If they didn't specify whether Nexus needs to use the proxy, we should
      -  689   -
               // still honor the property if it's set.
      -  690  0
               if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
      -  691   -
                   try {
      -  692  0
                       return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY);
      -  693  0
                   } catch (InvalidSettingException ise) {
      -  694  0
                       return true;
      -  695   -
                   }
      -  696   -
               } else {
      -  697  0
                   return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
      -  698   -
               }
      -  699  
           }
      -  700   +  688  
       
      -  701   +  689  
           /**
      -  702   -
            * Displays the command line help message to the standard output.
      -  703   +  690   +
            * Returns true if the disableCentral command line argument was specified.
      +  691   +
            *
      +  692   +
            * @return true if the disableCentral command line argument was specified;
      +  693   +
            * otherwise false
      +  694  
            */
      +  695   +
           public boolean isCentralDisabled() {
      +  696  0
               return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL);
      +  697   +
           }
      +  698   +
       
      +  699   +
           /**
      +  700   +
            * Returns the url to the nexus server if one was specified.
      +  701   +
            *
      +  702   +
            * @return the url to the nexus server; if none was specified this will
      +  703   +
            * return null;
       704   -
           public void printHelp() {
      -  705  2
               final HelpFormatter formatter = new HelpFormatter();
      -  706  2
               final Options options = new Options();
      -  707  2
               addStandardOptions(options);
      -  708  2
               if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
      -  709  0
                   addAdvancedOptions(options);
      +
            */
      +  705   +
           public String getNexusUrl() {
      +  706  0
               if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) {
      +  707  0
                   return null;
      +  708   +
               } else {
      +  709  0
                   return line.getOptionValue(ARGUMENT.NEXUS_URL);
       710  
               }
      -  711  4
               final String helpMsg = String.format("%n%s"
      +  711   +
           }
       712   -
                       + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
      +
       
       713   -
                       + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n",
      -  714  2
                       Settings.getString("application.name", "DependencyCheck"),
      -  715  2
                       Settings.getString("application.name", "DependencyCheck"));
      +
           /**
      +  714   +
            * Returns true if the Nexus Analyzer should use the configured proxy to
      +  715   +
            * connect to Nexus; otherwise false is returned.
       716   -
       
      -  717  2
               formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
      +
            *
      +  717   +
            * @return true if the Nexus Analyzer should use the configured proxy to
       718   -
                       helpMsg,
      +
            * connect to Nexus; otherwise false
       719   -
                       options,
      +
            */
       720   -
                       "",
      +
           public boolean isNexusUsesProxy() {
       721   -
                       true);
      -  722  2
           }
      -  723   -
       
      +
               // If they didn't specify whether Nexus needs to use the proxy, we should
      +  722   +
               // still honor the property if it's set.
      +  723  0
               if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
       724   -
           /**
      -  725   -
            * Retrieves the file command line parameter(s) specified for the 'scan' argument.
      -  726   -
            *
      -  727   -
            * @return the file paths specified on the command line for scan
      +
                   try {
      +  725  0
                       return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY);
      +  726  0
                   } catch (InvalidSettingException ise) {
      +  727  0
                       return true;
       728   -
            */
      +
                   }
       729   -
           public String[] getScanFiles() {
      -  730  3
               return line.getOptionValues(ARGUMENT.SCAN);
      +
               } else {
      +  730  0
                   return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
       731   -
           }
      +
               }
       732   -
       
      +
           }
       733   -
           /**
      +
       
       734   -
            * Retrieves the list of excluded file patterns specified by the 'exclude' argument.
      +
           /**
       735   -
            *
      +
            * Displays the command line help message to the standard output.
       736   -
            * @return the excluded file patterns
      +
            */
       737   -
            */
      -  738   -
           public String[] getExcludeList() {
      -  739  0
               return line.getOptionValues(ARGUMENT.EXCLUDE);
      -  740   -
           }
      -  741   -
       
      -  742   -
           /**
      +
           public void printHelp() {
      +  738  4
               final HelpFormatter formatter = new HelpFormatter();
      +  739  4
               final Options options = new Options();
      +  740  4
               addStandardOptions(options);
      +  741  4
               if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
      +  742  0
                   addAdvancedOptions(options);
       743   -
            * Returns the directory to write the reports to specified on the command line.
      -  744   -
            *
      +
               }
      +  744  8
               final String helpMsg = String.format("%n%s"
       745   -
            * @return the path to the reports directory.
      +
                       + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
       746   -
            */
      -  747   -
           public String getReportDirectory() {
      -  748  1
               return line.getOptionValue(ARGUMENT.OUT, ".");
      +
                       + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n",
      +  747  4
                       Settings.getString("application.name", "DependencyCheck"),
      +  748  4
                       Settings.getString("application.name", "DependencyCheck"));
       749   -
           }
      -  750  
       
      +  750  4
               formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
       751   -
           /**
      +
                       helpMsg,
       752   -
            * Returns the path to Mono for .NET Assembly analysis on non-windows systems.
      +
                       options,
       753   -
            *
      +
                       "",
       754   -
            * @return the path to Mono
      -  755   -
            */
      +
                       true);
      +  755  4
           }
       756   -
           public String getPathToMono() {
      -  757  1
               return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
      +
       
      +  757   +
           /**
       758   -
           }
      +
            * Retrieves the file command line parameter(s) specified for the 'scan'
       759   -
       
      +
            * argument.
       760   -
           /**
      +
            *
       761   -
            * Returns the path to bundle-audit for Ruby bundle analysis.
      +
            * @return the file paths specified on the command line for scan
       762   -
            *
      +
            */
       763   -
            * @return the path to Mono
      -  764   -
            */
      +
           public String[] getScanFiles() {
      +  764  6
               return line.getOptionValues(ARGUMENT.SCAN);
       765   -
           public String getPathToBundleAudit() {
      -  766  0
               return line.getOptionValue(ARGUMENT.PATH_TO_BUNDLE_AUDIT);
      +
           }
      +  766   +
       
       767   -
           }
      +
           /**
       768   -
       
      +
            * Retrieves the list of excluded file patterns specified by the 'exclude'
       769   -
           /**
      +
            * argument.
       770   -
            * Returns the output format specified on the command line. Defaults to HTML if no format was specified.
      -  771  
            *
      +  771   +
            * @return the excluded file patterns
       772   -
            * @return the output format name.
      -  773  
            */
      -  774   -
           public String getReportFormat() {
      -  775  1
               return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
      -  776   +  773   +
           public String[] getExcludeList() {
      +  774  0
               return line.getOptionValues(ARGUMENT.EXCLUDE);
      +  775  
           }
      -  777   +  776  
       
      -  778   +  777  
           /**
      +  778   +
            * Returns the directory to write the reports to specified on the command
       779   -
            * Returns the application name specified on the command line.
      +
            * line.
       780  
            *
       781   -
            * @return the application name.
      +
            * @return the path to the reports directory.
       782  
            */
       783   -
           public String getProjectName() {
      -  784  0
               final String appName = line.getOptionValue(ARGUMENT.APP_NAME);
      -  785  0
               String name = line.getOptionValue(ARGUMENT.PROJECT);
      -  786  0
               if (name == null && appName != null) {
      -  787  0
                   name = appName;
      -  788  0
                   LOGGER.warn("The '" + ARGUMENT.APP_NAME + "' argument should no longer be used; use '" + ARGUMENT.PROJECT + "' instead.");
      +
           public String getReportDirectory() {
      +  784  2
               return line.getOptionValue(ARGUMENT.OUT, ".");
      +  785   +
           }
      +  786   +
       
      +  787   +
           /**
      +  788   +
            * Returns the path to Mono for .NET Assembly analysis on non-windows
       789   -
               }
      -  790  0
               return name;
      +
            * systems.
      +  790   +
            *
       791   -
           }
      +
            * @return the path to Mono
       792   -
       
      +
            */
       793   -
           /**
      -  794   -
            * Returns the base URL for the CVE 1.2 XMl file.
      +
           public String getPathToMono() {
      +  794  2
               return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
       795   -
            *
      +
           }
       796   -
            * @return the URL to the CVE 1.2 XML file.
      +
       
       797   -
            */
      +
           /**
       798   -
           public String getBaseCve12Url() {
      -  799  1
               return line.getOptionValue(ARGUMENT.CVE_BASE_12);
      +
            * Returns the path to bundle-audit for Ruby bundle analysis.
      +  799   +
            *
       800   -
           }
      +
            * @return the path to Mono
       801   -
       
      +
            */
       802   -
           /**
      -  803   -
            * Returns the base URL for the CVE 2.0 XMl file.
      +
           public String getPathToBundleAudit() {
      +  803  0
               return line.getOptionValue(ARGUMENT.PATH_TO_BUNDLE_AUDIT);
       804   -
            *
      +
           }
       805   -
            * @return the URL to the CVE 2.0 XML file.
      +
       
       806   -
            */
      +
           /**
       807   -
           public String getBaseCve20Url() {
      -  808  1
               return line.getOptionValue(ARGUMENT.CVE_BASE_20);
      +
            * Returns the output format specified on the command line. Defaults to HTML
      +  808   +
            * if no format was specified.
       809   -
           }
      +
            *
       810   -
       
      +
            * @return the output format name.
       811   -
           /**
      +
            */
       812   -
            * Returns the URL for the modified CVE 1.2 XMl file.
      -  813   -
            *
      +
           public String getReportFormat() {
      +  813  2
               return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
       814   -
            * @return the URL to the modified CVE 1.2 XML file.
      +
           }
       815   -
            */
      +
       
       816   -
           public String getModifiedCve12Url() {
      -  817  1
               return line.getOptionValue(ARGUMENT.CVE_MOD_12);
      +
           /**
      +  817   +
            * Returns the application name specified on the command line.
       818   -
           }
      +
            *
       819   -
       
      +
            * @return the application name.
       820   -
           /**
      +
            */
       821   -
            * Returns the URL for the modified CVE 2.0 XMl file.
      -  822   -
            *
      -  823   -
            * @return the URL to the modified CVE 2.0 XML file.
      -  824   -
            */
      -  825   -
           public String getModifiedCve20Url() {
      -  826  1
               return line.getOptionValue(ARGUMENT.CVE_MOD_20);
      +
           public String getProjectName() {
      +  822  0
               final String appName = line.getOptionValue(ARGUMENT.APP_NAME);
      +  823  0
               String name = line.getOptionValue(ARGUMENT.PROJECT);
      +  824  0
               if (name == null && appName != null) {
      +  825  0
                   name = appName;
      +  826  0
                   LOGGER.warn("The '" + ARGUMENT.APP_NAME + "' argument should no longer be used; use '" + ARGUMENT.PROJECT + "' instead.");
       827   -
           }
      -  828   -
       
      +
               }
      +  828  0
               return name;
       829   -
           /**
      +
           }
       830   -
            * Returns the connection timeout.
      +
       
       831   -
            *
      +
           /**
       832   -
            * @return the connection timeout
      +
            * Returns the base URL for the CVE 1.2 XMl file.
       833   -
            */
      +
            *
       834   -
           public String getConnectionTimeout() {
      -  835  0
               return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT);
      +
            * @return the URL to the CVE 1.2 XML file.
      +  835   +
            */
       836   -
           }
      -  837   -
       
      +
           public String getBaseCve12Url() {
      +  837  2
               return line.getOptionValue(ARGUMENT.CVE_BASE_12);
       838   -
           /**
      +
           }
       839   -
            * Returns the proxy server.
      +
       
       840   -
            *
      +
           /**
       841   -
            * @return the proxy server
      +
            * Returns the base URL for the CVE 2.0 XMl file.
       842   -
            */
      +
            *
       843   -
           @SuppressWarnings("deprecation")
      +
            * @return the URL to the CVE 2.0 XML file.
       844   -
           public String getProxyServer() {
      +
            */
       845   +
           public String getBaseCve20Url() {
      +  846  2
               return line.getOptionValue(ARGUMENT.CVE_BASE_20);
      +  847   +
           }
      +  848  
       
      -  846  0
               String server = line.getOptionValue(ARGUMENT.PROXY_SERVER);
      -  847  0
               if (server == null) {
      -  848  0
                   server = line.getOptionValue(ARGUMENT.PROXY_URL);
      -  849  0
                   if (server != null) {
      -  850  0
                       LOGGER.warn("An old command line argument 'proxyurl' was detected; use proxyserver instead");
      +  849   +
           /**
      +  850   +
            * Returns the URL for the modified CVE 1.2 XMl file.
       851   -
                   }
      +
            *
       852   -
               }
      -  853  0
               return server;
      +
            * @return the URL to the modified CVE 1.2 XML file.
      +  853   +
            */
       854   -
           }
      -  855   -
       
      +
           public String getModifiedCve12Url() {
      +  855  2
               return line.getOptionValue(ARGUMENT.CVE_MOD_12);
       856   -
           /**
      +
           }
       857   -
            * Returns the proxy port.
      +
       
       858   -
            *
      +
           /**
       859   -
            * @return the proxy port
      +
            * Returns the URL for the modified CVE 2.0 XMl file.
       860   -
            */
      +
            *
       861   -
           public String getProxyPort() {
      -  862  0
               return line.getOptionValue(ARGUMENT.PROXY_PORT);
      +
            * @return the URL to the modified CVE 2.0 XML file.
      +  862   +
            */
       863   -
           }
      -  864   -
       
      +
           public String getModifiedCve20Url() {
      +  864  2
               return line.getOptionValue(ARGUMENT.CVE_MOD_20);
       865   -
           /**
      +
           }
       866   -
            * Returns the proxy username.
      +
       
       867   -
            *
      +
           /**
       868   -
            * @return the proxy username
      +
            * Returns the connection timeout.
       869   -
            */
      +
            *
       870   -
           public String getProxyUsername() {
      -  871  0
               return line.getOptionValue(ARGUMENT.PROXY_USERNAME);
      +
            * @return the connection timeout
      +  871   +
            */
       872   -
           }
      -  873   -
       
      +
           public String getConnectionTimeout() {
      +  873  0
               return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT);
       874   -
           /**
      +
           }
       875   -
            * Returns the proxy password.
      +
       
       876   -
            *
      +
           /**
       877   -
            * @return the proxy password
      +
            * Returns the proxy server.
       878   -
            */
      +
            *
       879   -
           public String getProxyPassword() {
      -  880  0
               return line.getOptionValue(ARGUMENT.PROXY_PASSWORD);
      +
            * @return the proxy server
      +  880   +
            */
       881   -
           }
      +
           @SuppressWarnings("deprecation")
       882   -
       
      +
           public String getProxyServer() {
       883   -
           /**
      -  884   -
            * Get the value of dataDirectory.
      -  885   -
            *
      -  886   -
            * @return the value of dataDirectory
      -  887   -
            */
      -  888   -
           public String getDataDirectory() {
      -  889  0
               return line.getOptionValue(ARGUMENT.DATA_DIRECTORY);
      +
       
      +  884  0
               String server = line.getOptionValue(ARGUMENT.PROXY_SERVER);
      +  885  0
               if (server == null) {
      +  886  0
                   server = line.getOptionValue(ARGUMENT.PROXY_URL);
      +  887  0
                   if (server != null) {
      +  888  0
                       LOGGER.warn("An old command line argument 'proxyurl' was detected; use proxyserver instead");
      +  889   +
                   }
       890   -
           }
      -  891   -
       
      +
               }
      +  891  0
               return server;
       892   -
           /**
      +
           }
       893   -
            * Returns the properties file specified on the command line.
      +
       
       894   -
            *
      +
           /**
       895   -
            * @return the properties file specified on the command line
      +
            * Returns the proxy port.
       896   -
            */
      +
            *
       897   -
           public File getPropertiesFile() {
      -  898  0
               final String path = line.getOptionValue(ARGUMENT.PROP);
      -  899  0
               if (path != null) {
      -  900  0
                   return new File(path);
      +
            * @return the proxy port
      +  898   +
            */
      +  899   +
           public String getProxyPort() {
      +  900  0
               return line.getOptionValue(ARGUMENT.PROXY_PORT);
       901   -
               }
      -  902  0
               return null;
      +
           }
      +  902   +
       
       903   -
           }
      +
           /**
       904   -
       
      +
            * Returns the proxy username.
       905   -
           /**
      +
            *
       906   -
            * Returns the path to the verbose log file.
      +
            * @return the proxy username
       907   -
            *
      +
            */
       908   -
            * @return the path to the verbose log file
      -  909   -
            */
      +
           public String getProxyUsername() {
      +  909  0
               return line.getOptionValue(ARGUMENT.PROXY_USERNAME);
       910   -
           public String getVerboseLog() {
      -  911  0
               return line.getOptionValue(ARGUMENT.VERBOSE_LOG);
      +
           }
      +  911   +
       
       912   -
           }
      +
           /**
       913   -
       
      +
            * Returns the proxy password.
       914   -
           /**
      +
            *
       915   -
            * Returns the path to the suppression file.
      +
            * @return the proxy password
       916   -
            *
      +
            */
       917   -
            * @return the path to the suppression file
      -  918   -
            */
      +
           public String getProxyPassword() {
      +  918  0
               return line.getOptionValue(ARGUMENT.PROXY_PASSWORD);
       919   -
           public String getSuppressionFile() {
      -  920  0
               return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE);
      +
           }
      +  920   +
       
       921   -
           }
      +
           /**
       922   -
       
      +
            * Get the value of dataDirectory.
       923   -
           /**
      +
            *
       924   -
            * <p>
      +
            * @return the value of dataDirectory
       925   -
            * Prints the manifest information to standard output.</p>
      +
            */
       926   -
            * <ul><li>Implementation-Title: ${pom.name}</li>
      -  927   -
            * <li>Implementation-Version: ${pom.version}</li></ul>
      +
           public String getDataDirectory() {
      +  927  0
               return line.getOptionValue(ARGUMENT.DATA_DIRECTORY);
       928   -
            */
      +
           }
       929   -
           public void printVersionInfo() {
      -  930  2
               final String version = String.format("%s version %s",
      -  931  1
                       Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"),
      -  932  1
                       Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
      -  933  1
               System.out.println(version);
      -  934  1
           }
      +
       
      +  930   +
           /**
      +  931   +
            * Returns the properties file specified on the command line.
      +  932   +
            *
      +  933   +
            * @return the properties file specified on the command line
      +  934   +
            */
       935   -
       
      -  936   -
           /**
      -  937   -
            * Checks if the auto update feature has been disabled. If it has been disabled via the command line this will return false.
      -  938   -
            *
      +
           public File getPropertiesFile() {
      +  936  0
               final String path = line.getOptionValue(ARGUMENT.PROP);
      +  937  0
               if (path != null) {
      +  938  0
                   return new File(path);
       939   -
            * @return <code>true</code> if auto-update is allowed; otherwise <code>false</code>
      -  940   -
            */
      -  941   -
           public boolean isAutoUpdate() {
      -  942  0
               return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
      -  943   -
           }
      -  944   -
       
      -  945   -
           /**
      -  946   -
            * Checks if the update only flag has been set.
      -  947   -
            *
      -  948   -
            * @return <code>true</code> if the update only flag has been set; otherwise <code>false</code>.
      -  949   -
            */
      -  950   -
           public boolean isUpdateOnly() {
      -  951  7
               return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY);
      -  952   -
           }
      -  953   -
       
      -  954   -
           /**
      -  955   -
            * Checks if the purge NVD flag has been set.
      -  956   -
            *
      -  957   -
            * @return <code>true</code> if the purge nvd flag has been set; otherwise <code>false</code>.
      -  958   -
            */
      -  959   -
           public boolean isPurge() {
      -  960  0
               return line != null && line.hasOption(ARGUMENT.PURGE_NVD);
      -  961   -
           }
      -  962   -
       
      -  963   -
           /**
      -  964   -
            * Returns the database driver name if specified; otherwise null is returned.
      -  965   -
            *
      -  966   -
            * @return the database driver name if specified; otherwise null is returned
      -  967   -
            */
      -  968   -
           public String getDatabaseDriverName() {
      -  969  0
               return line.getOptionValue(ARGUMENT.DB_DRIVER);
      -  970   -
           }
      -  971   -
       
      -  972   -
           /**
      -  973   -
            * Returns the database driver path if specified; otherwise null is returned.
      -  974   -
            *
      -  975   -
            * @return the database driver name if specified; otherwise null is returned
      -  976   -
            */
      -  977   -
           public String getDatabaseDriverPath() {
      -  978  0
               return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH);
      -  979   -
           }
      -  980   -
       
      -  981   -
           /**
      -  982   -
            * Returns the database connection string if specified; otherwise null is returned.
      -  983   -
            *
      -  984   -
            * @return the database connection string if specified; otherwise null is returned
      -  985   -
            */
      -  986   -
           public String getConnectionString() {
      -  987  0
               return line.getOptionValue(ARGUMENT.CONNECTION_STRING);
      -  988   -
           }
      -  989   -
       
      -  990   -
           /**
      -  991   -
            * Returns the database database user name if specified; otherwise null is returned.
      -  992   -
            *
      -  993   -
            * @return the database database user name if specified; otherwise null is returned
      -  994   -
            */
      -  995   -
           public String getDatabaseUser() {
      -  996  0
               return line.getOptionValue(ARGUMENT.DB_NAME);
      -  997   -
           }
      -  998   -
       
      -  999   -
           /**
      -  1000   -
            * Returns the database database password if specified; otherwise null is returned.
      -  1001   -
            *
      -  1002   -
            * @return the database database password if specified; otherwise null is returned
      -  1003   -
            */
      -  1004   -
           public String getDatabasePassword() {
      -  1005  0
               return line.getOptionValue(ARGUMENT.DB_PASSWORD);
      -  1006   -
           }
      -  1007   -
       
      -  1008   -
           /**
      -  1009   -
            * Returns the additional Extensions if specified; otherwise null is returned.
      -  1010   -
            *
      -  1011   -
            * @return the additional Extensions; otherwise null is returned
      -  1012   -
            */
      -  1013   -
           public String getAdditionalZipExtensions() {
      -  1014  0
               return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS);
      -  1015   -
           }
      -  1016   -
       
      -  1017   -
           /**
      -  1018   -
            * Get the value of cveValidForHours.
      -  1019   -
            *
      -  1020   -
            * @return the value of cveValidForHours
      -  1021   -
            */
      -  1022   -
           public Integer getCveValidForHours() {
      -  1023  0
               final String v = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS);
      -  1024  0
               if (v != null) {
      -  1025  0
                   return Integer.parseInt(v);
      -  1026  
               }
      -  1027  0
               return null;
      -  1028   +  940  0
               return null;
      +  941  
           }
      -  1029   +  942  
       
      -  1030   +  943  
           /**
      -  1031   -
            * A collection of static final strings that represent the possible command line arguments.
      -  1032   +  944   +
            * Returns the path to the verbose log file.
      +  945   +
            *
      +  946   +
            * @return the path to the verbose log file
      +  947  
            */
      -  1033  0
           public static class ARGUMENT {
      -  1034   +  948   +
           public String getVerboseLog() {
      +  949  0
               return line.getOptionValue(ARGUMENT.VERBOSE_LOG);
      +  950   +
           }
      +  951  
       
      +  952   +
           /**
      +  953   +
            * Returns the path to the suppression file.
      +  954   +
            *
      +  955   +
            * @return the path to the suppression file
      +  956   +
            */
      +  957   +
           public String getSuppressionFile() {
      +  958  0
               return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE);
      +  959   +
           }
      +  960   +
       
      +  961   +
           /**
      +  962   +
            * <p>
      +  963   +
            * Prints the manifest information to standard output.</p>
      +  964   +
            * <ul><li>Implementation-Title: ${pom.name}</li>
      +  965   +
            * <li>Implementation-Version: ${pom.version}</li></ul>
      +  966   +
            */
      +  967   +
           public void printVersionInfo() {
      +  968  4
               final String version = String.format("%s version %s",
      +  969  2
                       Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"),
      +  970  2
                       Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
      +  971  2
               System.out.println(version);
      +  972  2
           }
      +  973   +
       
      +  974   +
           /**
      +  975   +
            * Checks if the auto update feature has been disabled. If it has been
      +  976   +
            * disabled via the command line this will return false.
      +  977   +
            *
      +  978   +
            * @return <code>true</code> if auto-update is allowed; otherwise
      +  979   +
            * <code>false</code>
      +  980   +
            */
      +  981   +
           public boolean isAutoUpdate() {
      +  982  0
               return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
      +  983   +
           }
      +  984   +
       
      +  985   +
           /**
      +  986   +
            * Checks if the update only flag has been set.
      +  987   +
            *
      +  988   +
            * @return <code>true</code> if the update only flag has been set; otherwise
      +  989   +
            * <code>false</code>.
      +  990   +
            */
      +  991   +
           public boolean isUpdateOnly() {
      +  992  14
               return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY);
      +  993   +
           }
      +  994   +
       
      +  995   +
           /**
      +  996   +
            * Checks if the purge NVD flag has been set.
      +  997   +
            *
      +  998   +
            * @return <code>true</code> if the purge nvd flag has been set; otherwise
      +  999   +
            * <code>false</code>.
      +  1000   +
            */
      +  1001   +
           public boolean isPurge() {
      +  1002  0
               return line != null && line.hasOption(ARGUMENT.PURGE_NVD);
      +  1003   +
           }
      +  1004   +
       
      +  1005   +
           /**
      +  1006   +
            * Returns the database driver name if specified; otherwise null is
      +  1007   +
            * returned.
      +  1008   +
            *
      +  1009   +
            * @return the database driver name if specified; otherwise null is returned
      +  1010   +
            */
      +  1011   +
           public String getDatabaseDriverName() {
      +  1012  0
               return line.getOptionValue(ARGUMENT.DB_DRIVER);
      +  1013   +
           }
      +  1014   +
       
      +  1015   +
           /**
      +  1016   +
            * Returns the database driver path if specified; otherwise null is
      +  1017   +
            * returned.
      +  1018   +
            *
      +  1019   +
            * @return the database driver name if specified; otherwise null is returned
      +  1020   +
            */
      +  1021   +
           public String getDatabaseDriverPath() {
      +  1022  0
               return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH);
      +  1023   +
           }
      +  1024   +
       
      +  1025   +
           /**
      +  1026   +
            * Returns the database connection string if specified; otherwise null is
      +  1027   +
            * returned.
      +  1028   +
            *
      +  1029   +
            * @return the database connection string if specified; otherwise null is
      +  1030   +
            * returned
      +  1031   +
            */
      +  1032   +
           public String getConnectionString() {
      +  1033  0
               return line.getOptionValue(ARGUMENT.CONNECTION_STRING);
      +  1034   +
           }
       1035   -
               /**
      +
       
       1036   -
                * The long CLI argument name specifying the directory/file to scan.
      +
           /**
       1037   -
                */
      +
            * Returns the database database user name if specified; otherwise null is
       1038   -
               public static final String SCAN = "scan";
      +
            * returned.
       1039   -
               /**
      +
            *
       1040   -
                * The short CLI argument name specifying the directory/file to scan.
      +
            * @return the database database user name if specified; otherwise null is
       1041   -
                */
      +
            * returned
       1042   -
               public static final String SCAN_SHORT = "s";
      +
            */
       1043   -
               /**
      -  1044   -
                * The long CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated.
      +
           public String getDatabaseUser() {
      +  1044  0
               return line.getOptionValue(ARGUMENT.DB_NAME);
       1045   -
                */
      +
           }
       1046   -
               public static final String DISABLE_AUTO_UPDATE = "noupdate";
      +
       
       1047   -
               /**
      +
           /**
       1048   -
                * The short CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated.
      +
            * Returns the database database password if specified; otherwise null is
       1049   -
                */
      +
            * returned.
       1050   -
               public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
      +
            *
       1051   -
               /**
      +
            * @return the database database password if specified; otherwise null is
       1052   -
                * The long CLI argument name specifying that only the update phase should be executed; no scan should be run.
      +
            * returned
       1053   -
                */
      +
            */
       1054   -
               public static final String UPDATE_ONLY = "updateonly";
      -  1055   -
               /**
      +
           public String getDatabasePassword() {
      +  1055  0
               return line.getOptionValue(ARGUMENT.DB_PASSWORD);
       1056   -
                * The long CLI argument name specifying that only the update phase should be executed; no scan should be run.
      +
           }
       1057   -
                */
      +
       
       1058   -
               public static final String PURGE_NVD = "purge";
      +
           /**
       1059   -
               /**
      +
            * Returns the additional Extensions if specified; otherwise null is
       1060   -
                * The long CLI argument name specifying the directory to write the reports to.
      +
            * returned.
       1061   -
                */
      +
            *
       1062   -
               public static final String OUT = "out";
      +
            * @return the additional Extensions; otherwise null is returned
       1063   -
               /**
      +
            */
       1064   -
                * The short CLI argument name specifying the directory to write the reports to.
      -  1065   -
                */
      +
           public String getAdditionalZipExtensions() {
      +  1065  0
               return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS);
       1066   -
               public static final String OUT_SHORT = "o";
      +
           }
       1067   -
               /**
      +
       
       1068   -
                * The long CLI argument name specifying the output format to write the reports to.
      +
           /**
       1069   -
                */
      +
            * Get the value of cveValidForHours.
       1070   -
               public static final String OUTPUT_FORMAT = "format";
      +
            *
       1071   -
               /**
      +
            * @return the value of cveValidForHours
       1072   -
                * The short CLI argument name specifying the output format to write the reports to.
      +
            */
       1073   -
                */
      -  1074   -
               public static final String OUTPUT_FORMAT_SHORT = "f";
      -  1075   -
               /**
      -  1076   -
                * The long CLI argument name specifying the name of the project to be scanned.
      +
           public Integer getCveValidForHours() {
      +  1074  0
               final String v = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS);
      +  1075  0
               if (v != null) {
      +  1076  0
                   return Integer.parseInt(v);
       1077   -
                */
      -  1078   -
               public static final String PROJECT = "project";
      +
               }
      +  1078  0
               return null;
       1079   -
               /**
      +
           }
       1080   -
                * The long CLI argument name specifying the name of the application to be scanned.
      +
       
       1081   -
                *
      +
           /**
       1082   -
                * @deprecated project should be used instead
      +
            * Returns true if the experimental analyzers are enabled.
       1083   -
                */
      +
            *
       1084   -
               @Deprecated
      +
            * @return true if the experimental analyzers are enabled; otherwise false
       1085   -
               public static final String APP_NAME = "app";
      +
            */
       1086   -
               /**
      -  1087   -
                * The short CLI argument name specifying the name of the application to be scanned.
      +
           public boolean isExperimentalEnabled() {
      +  1087  0
               return line.hasOption(ARGUMENT.EXPERIMENTAL);
       1088   -
                *
      +
           }
       1089   -
                * @deprecated project should be used instead
      +
       
       1090   -
                */
      +
           /**
       1091   -
               @Deprecated
      +
            * A collection of static final strings that represent the possible command
       1092   -
               public static final String APP_NAME_SHORT = "a";
      +
            * line arguments.
       1093   -
               /**
      -  1094   -
                * The long CLI argument name asking for help.
      +
            */
      +  1094  0
           public static class ARGUMENT {
       1095   -
                */
      +
       
       1096   -
               public static final String HELP = "help";
      +
               /**
       1097   -
               /**
      +
                * The long CLI argument name specifying the directory/file to scan.
       1098   -
                * The long CLI argument name asking for advanced help.
      +
                */
       1099   -
                */
      +
               public static final String SCAN = "scan";
       1100   -
               public static final String ADVANCED_HELP = "advancedHelp";
      +
               /**
       1101   -
               /**
      +
                * The short CLI argument name specifying the directory/file to scan.
       1102   -
                * The short CLI argument name asking for help.
      -  1103  
                */
      +  1103   +
               public static final String SCAN_SHORT = "s";
       1104   -
               public static final String HELP_SHORT = "h";
      -  1105  
               /**
      +  1105   +
                * The long CLI argument name specifying that the CPE/CVE/etc. data
       1106   -
                * The long CLI argument name asking for the version.
      +
                * should not be automatically updated.
       1107  
                */
       1108   -
               public static final String VERSION_SHORT = "v";
      +
               public static final String DISABLE_AUTO_UPDATE = "noupdate";
       1109  
               /**
       1110   -
                * The short CLI argument name asking for the version.
      +
                * The short CLI argument name specifying that the CPE/CVE/etc. data
       1111   -
                */
      +
                * should not be automatically updated.
       1112   -
               public static final String VERSION = "version";
      +
                */
       1113   -
               /**
      +
               public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
       1114   -
                * The CLI argument name indicating the proxy port.
      +
               /**
       1115   -
                */
      +
                * The long CLI argument name specifying that only the update phase
       1116   -
               public static final String PROXY_PORT = "proxyport";
      +
                * should be executed; no scan should be run.
       1117   -
               /**
      +
                */
       1118   -
                * The CLI argument name indicating the proxy server.
      +
               public static final String UPDATE_ONLY = "updateonly";
       1119   -
                */
      +
               /**
       1120   -
               public static final String PROXY_SERVER = "proxyserver";
      +
                * The long CLI argument name specifying that only the update phase
       1121   -
               /**
      +
                * should be executed; no scan should be run.
       1122   -
                * The CLI argument name indicating the proxy url.
      +
                */
       1123   -
                *
      +
               public static final String PURGE_NVD = "purge";
       1124   -
                * @deprecated use {@link #PROXY_SERVER} instead
      +
               /**
       1125   -
                */
      +
                * The long CLI argument name specifying the directory to write the
       1126   -
               @Deprecated
      +
                * reports to.
       1127   -
               public static final String PROXY_URL = "proxyurl";
      +
                */
       1128   -
               /**
      +
               public static final String OUT = "out";
       1129   -
                * The CLI argument name indicating the proxy username.
      +
               /**
       1130   -
                */
      +
                * The short CLI argument name specifying the directory to write the
       1131   -
               public static final String PROXY_USERNAME = "proxyuser";
      +
                * reports to.
       1132   -
               /**
      +
                */
       1133   -
                * The CLI argument name indicating the proxy password.
      +
               public static final String OUT_SHORT = "o";
       1134   -
                */
      +
               /**
       1135   -
               public static final String PROXY_PASSWORD = "proxypass";
      +
                * The long CLI argument name specifying the output format to write the
       1136   -
               /**
      +
                * reports to.
       1137   -
                * The short CLI argument name indicating the connection timeout.
      -  1138  
                */
      +  1138   +
               public static final String OUTPUT_FORMAT = "format";
       1139   -
               public static final String CONNECTION_TIMEOUT_SHORT = "c";
      -  1140  
               /**
      +  1140   +
                * The short CLI argument name specifying the output format to write the
       1141   -
                * The CLI argument name indicating the connection timeout.
      +
                * reports to.
       1142  
                */
       1143   -
               public static final String CONNECTION_TIMEOUT = "connectiontimeout";
      +
               public static final String OUTPUT_FORMAT_SHORT = "f";
       1144  
               /**
       1145   -
                * The short CLI argument name for setting the location of an additional properties file.
      +
                * The long CLI argument name specifying the name of the project to be
       1146   -
                */
      +
                * scanned.
       1147   -
               public static final String PROP_SHORT = "P";
      -  1148   -
               /**
      -  1149   -
                * The CLI argument name for setting the location of an additional properties file.
      -  1150  
                */
      -  1151   -
               public static final String PROP = "propertyfile";
      -  1152   +  1148   +
               public static final String PROJECT = "project";
      +  1149  
               /**
      +  1150   +
                * The long CLI argument name specifying the name of the application to
      +  1151   +
                * be scanned.
      +  1152   +
                *
       1153   -
                * The CLI argument name for setting the location of the data directory.
      +
                * @deprecated project should be used instead
       1154  
                */
       1155   -
               public static final String DATA_DIRECTORY = "data";
      +
               @Deprecated
       1156   -
               /**
      +
               public static final String APP_NAME = "app";
       1157   -
                * The CLI argument name for setting the URL for the CVE Data Files.
      -  1158   -
                */
      -  1159   -
               public static final String CVE_MOD_12 = "cveUrl12Modified";
      -  1160  
               /**
      +  1158   +
                * The short CLI argument name specifying the name of the application to
      +  1159   +
                * be scanned.
      +  1160   +
                *
       1161   -
                * The CLI argument name for setting the URL for the CVE Data Files.
      +
                * @deprecated project should be used instead
       1162  
                */
       1163   -
               public static final String CVE_MOD_20 = "cveUrl20Modified";
      +
               @Deprecated
       1164   -
               /**
      +
               public static final String APP_NAME_SHORT = "a";
       1165   -
                * The CLI argument name for setting the URL for the CVE Data Files.
      +
               /**
       1166   -
                */
      +
                * The long CLI argument name asking for help.
       1167   -
               public static final String CVE_BASE_12 = "cveUrl12Base";
      +
                */
       1168   -
               /**
      +
               public static final String HELP = "help";
       1169   -
                * The CLI argument name for setting the URL for the CVE Data Files.
      +
               /**
       1170   -
                */
      +
                * The long CLI argument name asking for advanced help.
       1171   -
               public static final String CVE_BASE_20 = "cveUrl20Base";
      +
                */
       1172   -
               /**
      +
               public static final String ADVANCED_HELP = "advancedHelp";
       1173   -
                * The short CLI argument name for setting the location of the data directory.
      +
               /**
       1174   -
                */
      +
                * The short CLI argument name asking for help.
       1175   -
               public static final String DATA_DIRECTORY_SHORT = "d";
      +
                */
       1176   -
               /**
      +
               public static final String HELP_SHORT = "h";
       1177   -
                * The CLI argument name for setting the location of the data directory.
      -  1178   -
                */
      -  1179   -
               public static final String VERBOSE_LOG = "log";
      -  1180  
               /**
      -  1181   -
                * The short CLI argument name for setting the location of the data directory.
      -  1182   +  1178   +
                * The long CLI argument name asking for the version.
      +  1179  
                */
      +  1180   +
               public static final String VERSION_SHORT = "v";
      +  1181   +
               /**
      +  1182   +
                * The short CLI argument name asking for the version.
       1183   -
               public static final String VERBOSE_LOG_SHORT = "l";
      +
                */
       1184   -
       
      +
               public static final String VERSION = "version";
       1185  
               /**
       1186   -
                * The CLI argument name for setting the depth of symbolic links that will be followed.
      +
                * The CLI argument name indicating the proxy port.
       1187  
                */
       1188   -
               public static final String SYM_LINK_DEPTH = "symLink";
      +
               public static final String PROXY_PORT = "proxyport";
       1189  
               /**
       1190   -
                * The CLI argument name for setting the location of the suppression file.
      +
                * The CLI argument name indicating the proxy server.
       1191  
                */
       1192   -
               public static final String SUPPRESSION_FILE = "suppression";
      +
               public static final String PROXY_SERVER = "proxyserver";
       1193  
               /**
       1194   -
                * The CLI argument name for setting the location of the suppression file.
      +
                * The CLI argument name indicating the proxy url.
       1195   -
                */
      +
                *
       1196   -
               public static final String CVE_VALID_FOR_HOURS = "cveValidForHours";
      +
                * @deprecated use {@link #PROXY_SERVER} instead
       1197   -
               /**
      +
                */
       1198   -
                * Disables the Jar Analyzer.
      +
               @Deprecated
       1199   -
                */
      +
               public static final String PROXY_URL = "proxyurl";
       1200   -
               public static final String DISABLE_JAR = "disableJar";
      +
               /**
       1201   -
               /**
      +
                * The CLI argument name indicating the proxy username.
       1202   -
                * Disables the Archive Analyzer.
      +
                */
       1203   -
                */
      +
               public static final String PROXY_USERNAME = "proxyuser";
       1204   -
               public static final String DISABLE_ARCHIVE = "disableArchive";
      +
               /**
       1205   -
               /**
      +
                * The CLI argument name indicating the proxy password.
       1206   -
                * Disables the Python Distribution Analyzer.
      +
                */
       1207   -
                */
      +
               public static final String PROXY_PASSWORD = "proxypass";
       1208   -
               public static final String DISABLE_PY_DIST = "disablePyDist";
      +
               /**
       1209   -
               /**
      +
                * The short CLI argument name indicating the connection timeout.
       1210   -
                * Disables the Python Package Analyzer.
      +
                */
       1211   -
                */
      +
               public static final String CONNECTION_TIMEOUT_SHORT = "c";
       1212   -
               public static final String DISABLE_PY_PKG = "disablePyPkg";
      +
               /**
       1213   -
               /**
      +
                * The CLI argument name indicating the connection timeout.
       1214   -
                * Disables the Python Package Analyzer.
      -  1215  
                */
      +  1215   +
               public static final String CONNECTION_TIMEOUT = "connectiontimeout";
       1216   -
               public static final String DISABLE_COMPOSER = "disableComposer";
      -  1217  
               /**
      +  1217   +
                * The short CLI argument name for setting the location of an additional
       1218   -
                * Disables the Ruby Gemspec Analyzer.
      +
                * properties file.
       1219  
                */
       1220   -
               public static final String DISABLE_RUBYGEMS = "disableRubygems";
      +
               public static final String PROP_SHORT = "P";
       1221  
               /**
       1222   -
                * Disables the Autoconf Analyzer.
      +
                * The CLI argument name for setting the location of an additional
       1223   -
                */
      +
                * properties file.
       1224   -
               public static final String DISABLE_AUTOCONF = "disableAutoconf";
      +
                */
       1225   -
               /**
      +
               public static final String PROP = "propertyfile";
       1226   -
                * Disables the Cmake Analyzer.
      +
               /**
       1227   -
                */
      +
                * The CLI argument name for setting the location of the data directory.
       1228   -
               public static final String DISABLE_CMAKE = "disableCmake";
      +
                */
       1229   -
               /**
      +
               public static final String DATA_DIRECTORY = "data";
       1230   -
                * Disables the Assembly Analyzer.
      +
               /**
       1231   -
                */
      +
                * The CLI argument name for setting the URL for the CVE Data Files.
       1232   -
               public static final String DISABLE_ASSEMBLY = "disableAssembly";
      +
                */
       1233   -
               /**
      +
               public static final String CVE_MOD_12 = "cveUrl12Modified";
       1234   -
                * Disables the Ruby Bundler Audit Analyzer.
      +
               /**
       1235   -
                */
      +
                * The CLI argument name for setting the URL for the CVE Data Files.
       1236   -
               public static final String DISABLE_BUNDLE_AUDIT = "disableBundleAudit";
      +
                */
       1237   -
               /**
      +
               public static final String CVE_MOD_20 = "cveUrl20Modified";
       1238   -
                * Disables the Nuspec Analyzer.
      +
               /**
       1239   -
                */
      +
                * The CLI argument name for setting the URL for the CVE Data Files.
       1240   -
               public static final String DISABLE_NUSPEC = "disableNuspec";
      +
                */
       1241   -
               /**
      +
               public static final String CVE_BASE_12 = "cveUrl12Base";
       1242   -
                * Disables the Central Analyzer.
      +
               /**
       1243   -
                */
      +
                * The CLI argument name for setting the URL for the CVE Data Files.
       1244   -
               public static final String DISABLE_CENTRAL = "disableCentral";
      +
                */
       1245   -
               /**
      +
               public static final String CVE_BASE_20 = "cveUrl20Base";
       1246   -
                * Disables the Nexus Analyzer.
      +
               /**
       1247   -
                */
      +
                * The short CLI argument name for setting the location of the data
       1248   -
               public static final String DISABLE_NEXUS = "disableNexus";
      +
                * directory.
       1249   -
               /**
      +
                */
       1250   -
                * Disables the OpenSSL Analyzer.
      +
               public static final String DATA_DIRECTORY_SHORT = "d";
       1251   -
                */
      +
               /**
       1252   -
               public static final String DISABLE_OPENSSL = "disableOpenSSL";
      +
                * The CLI argument name for setting the location of the data directory.
       1253   -
               /**
      +
                */
       1254   -
                * Disables the Node.js Package Analyzer.
      +
               public static final String VERBOSE_LOG = "log";
       1255   -
                */
      -  1256   -
               public static final String DISABLE_NODE_JS = "disableNodeJS";
      -  1257  
               /**
      +  1256   +
                * The short CLI argument name for setting the location of the data
      +  1257   +
                * directory.
       1258   -
                * The URL of the nexus server.
      -  1259  
                */
      +  1259   +
               public static final String VERBOSE_LOG_SHORT = "l";
       1260   -
               public static final String NEXUS_URL = "nexus";
      +
       
       1261  
               /**
       1262   -
                * Whether or not the defined proxy should be used when connecting to Nexus.
      +
                * The CLI argument name for setting the depth of symbolic links that
       1263   -
                */
      +
                * will be followed.
       1264   -
               public static final String NEXUS_USES_PROXY = "nexusUsesProxy";
      +
                */
       1265   -
               /**
      +
               public static final String SYM_LINK_DEPTH = "symLink";
       1266   -
                * The CLI argument name for setting the connection string.
      +
               /**
       1267   -
                */
      +
                * The CLI argument name for setting the location of the suppression
       1268   -
               public static final String CONNECTION_STRING = "connectionString";
      +
                * file.
       1269   -
               /**
      +
                */
       1270   -
                * The CLI argument name for setting the database user name.
      +
               public static final String SUPPRESSION_FILE = "suppression";
       1271   -
                */
      +
               /**
       1272   -
               public static final String DB_NAME = "dbUser";
      +
                * The CLI argument name for setting the location of the suppression
       1273   -
               /**
      +
                * file.
       1274   -
                * The CLI argument name for setting the database password.
      +
                */
       1275   -
                */
      +
               public static final String CVE_VALID_FOR_HOURS = "cveValidForHours";
       1276   -
               public static final String DB_PASSWORD = "dbPassword";
      +
               /**
       1277   -
               /**
      +
                * Disables the Jar Analyzer.
       1278   -
                * The CLI argument name for setting the database driver name.
      +
                */
       1279   -
                */
      +
               public static final String DISABLE_JAR = "disableJar";
       1280   -
               public static final String DB_DRIVER = "dbDriverName";
      +
               /**
       1281   -
               /**
      +
                * Disables the Archive Analyzer.
       1282   -
                * The CLI argument name for setting the path to the database driver; in case it is not on the class path.
      +
                */
       1283   -
                */
      +
               public static final String DISABLE_ARCHIVE = "disableArchive";
       1284   -
               public static final String DB_DRIVER_PATH = "dbDriverPath";
      +
               /**
       1285   -
               /**
      +
                * Disables the Python Distribution Analyzer.
       1286   -
                * The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems.
      +
                */
       1287   -
                */
      +
               public static final String DISABLE_PY_DIST = "disablePyDist";
       1288   -
               public static final String PATH_TO_MONO = "mono";
      +
               /**
       1289   -
               /**
      +
                * Disables the Python Package Analyzer.
       1290   -
                * The CLI argument name for setting extra extensions.
      +
                */
       1291   -
                */
      +
               public static final String DISABLE_PY_PKG = "disablePyPkg";
       1292   -
               public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
      +
               /**
       1293   -
               /**
      +
                * Disables the Python Package Analyzer.
       1294   -
                * Exclude path argument.
      +
                */
       1295   -
                */
      +
               public static final String DISABLE_COMPOSER = "disableComposer";
       1296   -
               public static final String EXCLUDE = "exclude";
      -  1297  
               /**
      +  1297   +
                * Disables the Ruby Gemspec Analyzer.
       1298   -
                * The CLI argument name for setting the path to bundle-audit for Ruby bundle analysis.
      -  1299  
                */
      +  1299   +
               public static final String DISABLE_RUBYGEMS = "disableRubygems";
       1300   -
               public static final String PATH_TO_BUNDLE_AUDIT = "bundleAudit";
      +
               /**
       1301   -
           }
      +
                * Disables the Autoconf Analyzer.
       1302   +
                */
      +  1303   +
               public static final String DISABLE_AUTOCONF = "disableAutoconf";
      +  1304   +
               /**
      +  1305   +
                * Disables the Cmake Analyzer.
      +  1306   +
                */
      +  1307   +
               public static final String DISABLE_CMAKE = "disableCmake";
      +  1308   +
               /**
      +  1309   +
                * Disables the Assembly Analyzer.
      +  1310   +
                */
      +  1311   +
               public static final String DISABLE_ASSEMBLY = "disableAssembly";
      +  1312   +
               /**
      +  1313   +
                * Disables the Ruby Bundler Audit Analyzer.
      +  1314   +
                */
      +  1315   +
               public static final String DISABLE_BUNDLE_AUDIT = "disableBundleAudit";
      +  1316   +
               /**
      +  1317   +
                * Disables the Nuspec Analyzer.
      +  1318   +
                */
      +  1319   +
               public static final String DISABLE_NUSPEC = "disableNuspec";
      +  1320   +
               /**
      +  1321   +
                * Disables the Central Analyzer.
      +  1322   +
                */
      +  1323   +
               public static final String DISABLE_CENTRAL = "disableCentral";
      +  1324   +
               /**
      +  1325   +
                * Disables the Nexus Analyzer.
      +  1326   +
                */
      +  1327   +
               public static final String DISABLE_NEXUS = "disableNexus";
      +  1328   +
               /**
      +  1329   +
                * Disables the OpenSSL Analyzer.
      +  1330   +
                */
      +  1331   +
               public static final String DISABLE_OPENSSL = "disableOpenSSL";
      +  1332   +
               /**
      +  1333   +
                * Disables the Node.js Package Analyzer.
      +  1334   +
                */
      +  1335   +
               public static final String DISABLE_NODE_JS = "disableNodeJS";
      +  1336   +
               /**
      +  1337   +
                * The URL of the nexus server.
      +  1338   +
                */
      +  1339   +
               public static final String NEXUS_URL = "nexus";
      +  1340   +
               /**
      +  1341   +
                * Whether or not the defined proxy should be used when connecting to
      +  1342   +
                * Nexus.
      +  1343   +
                */
      +  1344   +
               public static final String NEXUS_USES_PROXY = "nexusUsesProxy";
      +  1345   +
               /**
      +  1346   +
                * The CLI argument name for setting the connection string.
      +  1347   +
                */
      +  1348   +
               public static final String CONNECTION_STRING = "connectionString";
      +  1349   +
               /**
      +  1350   +
                * The CLI argument name for setting the database user name.
      +  1351   +
                */
      +  1352   +
               public static final String DB_NAME = "dbUser";
      +  1353   +
               /**
      +  1354   +
                * The CLI argument name for setting the database password.
      +  1355   +
                */
      +  1356   +
               public static final String DB_PASSWORD = "dbPassword";
      +  1357   +
               /**
      +  1358   +
                * The CLI argument name for setting the database driver name.
      +  1359   +
                */
      +  1360   +
               public static final String DB_DRIVER = "dbDriverName";
      +  1361   +
               /**
      +  1362   +
                * The CLI argument name for setting the path to the database driver; in
      +  1363   +
                * case it is not on the class path.
      +  1364   +
                */
      +  1365   +
               public static final String DB_DRIVER_PATH = "dbDriverPath";
      +  1366   +
               /**
      +  1367   +
                * The CLI argument name for setting the path to mono for .NET Assembly
      +  1368   +
                * analysis on non-windows systems.
      +  1369   +
                */
      +  1370   +
               public static final String PATH_TO_MONO = "mono";
      +  1371   +
               /**
      +  1372   +
                * The CLI argument name for setting extra extensions.
      +  1373   +
                */
      +  1374   +
               public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
      +  1375   +
               /**
      +  1376   +
                * Exclude path argument.
      +  1377   +
                */
      +  1378   +
               public static final String EXCLUDE = "exclude";
      +  1379   +
               /**
      +  1380   +
                * The CLI argument name for setting the path to bundle-audit for Ruby
      +  1381   +
                * bundle analysis.
      +  1382   +
                */
      +  1383   +
               public static final String PATH_TO_BUNDLE_AUDIT = "bundleAudit";
      +  1384   +
               /**
      +  1385   +
                * The CLI argument to enable the experimental analyzers.
      +  1386   +
                */
      +  1387   +
               private static final String EXPERIMENTAL = "enableExperimental";
      +  1388   +
           }
      +  1389  
       }
      - + diff --git a/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html b/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html index b025d6b30..055f5d9b7 100644 --- a/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html +++ b/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html @@ -143,6 +143,6 @@
       }
      - + diff --git a/dependency-check-cli/dependency-analysis.html b/dependency-check-cli/dependency-analysis.html index 67c5c1374..f54078dd6 100644 --- a/dependency-check-cli/dependency-analysis.html +++ b/dependency-check-cli/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Dependencies Report @@ -52,7 +52,7 @@ @@ -222,9 +222,6 @@ developed using - - - built on cloudbees @@ -257,7 +254,7 @@ org.owasp dependency-check-core -1.3.6 +1.4.0 compile jar @@ -265,7 +262,7 @@ org.owasp dependency-check-utils -1.3.6 +1.4.0 compile jar @@ -297,7 +294,7 @@ org.apache.ant ant -1.9.6 +1.9.7 compile jar diff --git a/dependency-check-cli/dependency-updates-report.html b/dependency-check-cli/dependency-updates-report.html index 662644371..20642290d 100644 --- a/dependency-check-cli/dependency-updates-report.html +++ b/dependency-check-cli/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Dependency Updates Report @@ -52,7 +52,7 @@ @@ -222,9 +222,6 @@ developed using - - - built on cloudbees @@ -240,7 +237,7 @@ # of dependencies using the latest version available -23 +24 # of dependencies where the next version available is smaller than an incremental version update @@ -248,11 +245,11 @@ # of dependencies where the next version available is an incremental version update -3 +1 # of dependencies where the next version available is a minor version update -6 +7 # of dependencies where the next version available is a major version update @@ -360,7 +357,7 @@ commons-io commons-io -2.4 +2.5 jar @@ -384,7 +381,7 @@ org.apache.ant ant -1.9.6 +1.9.7 jar @@ -396,7 +393,7 @@ org.apache.ant ant-testutil -1.9.6 +1.9.7 jar @@ -477,39 +474,39 @@ 4.8.0 5.0.0 - + org.apache.maven maven-core -3.3.3 +3.3.9 jar -3.3.9 + - + org.apache.maven maven-plugin-api -3.3.3 +3.3.9 jar -3.3.9 + - + org.apache.maven maven-settings -3.3.3 +3.3.9 jar -3.3.9 + @@ -585,7 +582,7 @@ - + org.jmockit jmockit 1.22 @@ -594,18 +591,18 @@ jar - +1.23 - + org.jsoup jsoup -1.8.3 +1.9.1 jar - +1.9.2 @@ -675,7 +672,7 @@ org.owasp dependency-check-core -1.3.6 +1.4.0 compile jar @@ -687,7 +684,7 @@ org.owasp dependency-check-utils -1.3.6 +1.4.0 compile jar @@ -808,7 +805,7 @@ jar Newer versions -1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191 Latest Minor +1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191
      1.4.192 Latest Minor

      com.sun.mail:mailapi

      @@ -898,7 +895,7 @@ - + @@ -946,7 +943,7 @@ - + @@ -970,7 +967,7 @@ - + @@ -1057,7 +1054,7 @@ -
      commons-io
      Current Version2.4
      2.5
      Scope
      ant
      Current Version1.9.6
      1.9.7
      Scope
      ant-testutil
      Current Version1.9.6
      1.9.7
      Scope
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-core

      @@ -1084,7 +1081,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1111,7 +1108,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1138,13 +1135,13 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.maven:maven-core

      - + @@ -1153,7 +1150,7 @@ - + @@ -1162,16 +1159,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-core
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-plugin-api

      - + @@ -1180,7 +1174,7 @@ - + @@ -1189,16 +1183,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-plugin-api
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-settings

      - + @@ -1207,7 +1198,7 @@ - + @@ -1216,10 +1207,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-settings
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven.plugin-testing:maven-plugin-testing-harness

      @@ -1369,7 +1357,7 @@
      - + @@ -1387,13 +1375,16 @@ -
      Status No newer versions available.
       There is at least one newer minor version available. Minor updates are sometimes passive.
      Group Id org.jmockit
      Typejar
      +jar + +Newer versions +1.23 Next Minor
      1.24 Latest Minor

      org.jsoup:jsoup

      - + @@ -1402,7 +1393,7 @@ - + @@ -1411,7 +1402,10 @@ -
      Status No newer versions available.
       There is at least one newer incremental version available. Incremental updates are typically passive.
      Group Id org.jsoup
      jsoup
      Current Version1.8.3
      1.9.1
      Scope
      Typejar
      +jar + +Newer versions +1.9.2 Next Incremental

      org.owasp:dependency-check-core

      @@ -1426,7 +1420,7 @@ - + @@ -1450,7 +1444,7 @@ - + diff --git a/dependency-check-cli/findbugs.html b/dependency-check-cli/findbugs.html index 7dc2ec137..c2380889f 100644 --- a/dependency-check-cli/findbugs.html +++ b/dependency-check-cli/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-cli – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ @@ -222,9 +222,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-cli/index.html b/dependency-check-cli/index.html index a7a7945c4..c095bd697 100644 --- a/dependency-check-cli/index.html +++ b/dependency-check-cli/index.html @@ -1,13 +1,13 @@ - + dependency-check-cli – About @@ -52,7 +52,7 @@ @@ -136,9 +136,6 @@ developed using - - - built on cloudbees @@ -150,7 +147,7 @@

      About

      OWASP dependency-check-cli is an command line tool that uses dependency-check-core to detect publicly disclosed vulnerabilities associated with the scanned project dependencies. The tool will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.

      Installation & Usage

      -

      Download the dependency-check command line tool here. Extract the zip file to a location on your computer and put the ‘bin’ directory into the path environment variable. On *nix systems you will likely need to make the shell script executable:

      +

      Download the dependency-check command line tool here. Extract the zip file to a location on your computer and put the ‘bin’ directory into the path environment variable. On *nix systems you will likely need to make the shell script executable:

      $ chmod +777 dependency-check.sh
      diff --git a/dependency-check-cli/integration.html b/dependency-check-cli/integration.html
      index dc34f8703..053b9fc48 100644
      --- a/dependency-check-cli/integration.html
      +++ b/dependency-check-cli/integration.html
      @@ -1,13 +1,13 @@
       
       
       
         
           
           
      -    
      +    
           
           dependency-check-cli – CI Management
           
      @@ -52,7 +52,7 @@
               
      @@ -187,9 +187,6 @@
             
                                                                                                           
               developed using
      -      
      -                                                                                                    
      -        built on cloudbees
             
                             
      @@ -200,11 +197,11 @@

      Overview

      -

      This project uses Continuous Integration System.

      +

      This project uses Travis CI.

      Access

      The following is a link to the continuous integration system used by the project:

      -
      +

      Notifiers

      No notifiers are defined. Please check back at a later date.

      diff --git a/dependency-check-cli/issue-tracking.html b/dependency-check-cli/issue-tracking.html index 22f735e49..e3f5076a2 100644 --- a/dependency-check-cli/issue-tracking.html +++ b/dependency-check-cli/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Issue Management @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-cli/license.html b/dependency-check-cli/license.html index dc8d79f01..ee36f8926 100644 --- a/dependency-check-cli/license.html +++ b/dependency-check-cli/license.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Project Licenses @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-cli/mail-lists.html b/dependency-check-cli/mail-lists.html index fdd60e275..68da4564e 100644 --- a/dependency-check-cli/mail-lists.html +++ b/dependency-check-cli/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Project Mailing Lists @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-cli/plugin-updates-report.html b/dependency-check-cli/plugin-updates-report.html index 7f14e7488..871aed4a8 100644 --- a/dependency-check-cli/plugin-updates-report.html +++ b/dependency-check-cli/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Plugin Updates Report @@ -52,7 +52,7 @@ @@ -222,9 +222,6 @@ developed using - - - built on cloudbees @@ -240,7 +237,7 @@ - + @@ -256,7 +253,7 @@ - + @@ -378,7 +375,7 @@ - + @@ -408,7 +405,7 @@ - + @@ -418,21 +415,21 @@ - + - + - - + + @@ -644,7 +641,7 @@ -
      dependency-check-core
      Current Version1.3.6
      1.4.0
      Scope compile
      dependency-check-utils
      Current Version1.3.6
      1.4.0
      Scope compile
      # of plugins using the latest version available19
      18
      # of plugins where the next version available is smaller than an incremental version update
      # of plugins where the next version available is a major version update0
      1
      # of plugins where a dependencies section containes a dependency with an updated version org.apache.maven.plugins maven-jar-plugin2.63.0.0 org.apache.maven.plugins maven-resources-plugin2.73.0.0 org.apache.maven.plugins maven-site-plugin3.53.5.1
      org.apache.maven.plugins maven-source-plugin2.42.4 3.0.0
      maven-jar-plugin
      Current Version2.6
      +3.0.0

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -689,7 +686,7 @@ -
      maven-resources-plugin
      Current Version2.7
      +3.0.0

      Plugin org.apache.maven.plugins:maven-site-plugin

      @@ -704,13 +701,13 @@ -
      maven-site-plugin
      Current Version3.5
      +3.5.1

      Plugin org.apache.maven.plugins:maven-source-plugin

      - + @@ -719,7 +716,10 @@ -
      Status No newer versions available.
       There is at least one newer major version available. Major updates are rarely passive.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      +2.4 + +Newer versions +3.0.0 Next Major

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-cli/pmd.html b/dependency-check-cli/pmd.html index 07095226f..966973c7a 100644 --- a/dependency-check-cli/pmd.html +++ b/dependency-check-cli/pmd.html @@ -1,13 +1,13 @@ - + dependency-check-cli – PMD Results @@ -52,7 +52,7 @@ @@ -222,9 +222,6 @@ developed using - - - built on cloudbees @@ -255,61 +252,61 @@ - + - + - + - + - + - + - - - - - - - + - + - + - + - + - + - + - + - + -
      Line
      Useless parentheses.130
      132
      Useless parentheses.495
      508
      Useless parentheses.504
      517
      Useless parentheses.513
      526
      Useless parentheses.540
      555
      Useless parentheses.549
      565
      Useless parentheses.558
      Useless parentheses.567
      Useless parentheses.576
      575
      Useless parentheses. 585
      Useless parentheses.594
      596
      Useless parentheses.603
      606
      Useless parentheses.612
      616
      Useless parentheses.621
      626
      Useless parentheses.630
      636
      Useless parentheses.639
      646
      Useless parentheses.648
      656
      Useless parentheses.657
      666
      Useless parentheses.666
      +676 + +Useless parentheses. +686 + +Useless parentheses. +696 diff --git a/dependency-check-cli/project-info.html b/dependency-check-cli/project-info.html index c4942a515..54ed9c99d 100644 --- a/dependency-check-cli/project-info.html +++ b/dependency-check-cli/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Project Information @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-cli/project-reports.html b/dependency-check-cli/project-reports.html index 57a6cf702..46fb80e5d 100644 --- a/dependency-check-cli/project-reports.html +++ b/dependency-check-cli/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Generated Reports @@ -52,7 +52,7 @@ @@ -222,9 +222,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-cli/project-summary.html b/dependency-check-cli/project-summary.html index beabd4792..f3beb1f65 100644 --- a/dependency-check-cli/project-summary.html +++ b/dependency-check-cli/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Project Summary @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees @@ -241,7 +238,7 @@ dependency-check-cli Version -1.3.6 +1.4.0 Type jar diff --git a/dependency-check-cli/source-repository.html b/dependency-check-cli/source-repository.html index 12c38f9fc..4431274fc 100644 --- a/dependency-check-cli/source-repository.html +++ b/dependency-check-cli/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Source Code Management @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-cli/surefire-report.html b/dependency-check-cli/surefire-report.html index fe7c0b550..faee48224 100644 --- a/dependency-check-cli/surefire-report.html +++ b/dependency-check-cli/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Surefire Report @@ -52,7 +52,7 @@ @@ -222,9 +222,6 @@ developed using - - - built on cloudbees @@ -269,7 +266,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.468
      +0.384

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -290,7 +287,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.468
      +0.384

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck

      @@ -312,7 +309,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.424 +0.383 CliParserTest @@ -321,7 +318,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.044

      +0.001

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -331,7 +328,7 @@ function toggleDisplay(elementId) { testEnsureCanonicalPath2 -0.324 +0.32 testEnsureCanonicalPath @@ -342,7 +339,7 @@ function toggleDisplay(elementId) { testParse_printHelp -0.028 +0 testParse_printVersionInfo @@ -350,7 +347,7 @@ function toggleDisplay(elementId) { testParse_help -0.004 +0 testParse_scan @@ -370,7 +367,7 @@ function toggleDisplay(elementId) { testParse_scan_unknownFile -0.004 +0 testParse_scan_withFileExists diff --git a/dependency-check-cli/taglist.html b/dependency-check-cli/taglist.html index d785c60a3..ae001dd8b 100644 --- a/dependency-check-cli/taglist.html +++ b/dependency-check-cli/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Tag List report @@ -52,7 +52,7 @@ @@ -222,9 +222,6 @@ developed using - - - built on cloudbees
      diff --git a/dependency-check-cli/team-list.html b/dependency-check-cli/team-list.html index a19058c81..be910782e 100644 --- a/dependency-check-cli/team-list.html +++ b/dependency-check-cli/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Project Team @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-cli/xref-test/index.html b/dependency-check-cli/xref-test/index.html index fd5c36ab1..314aaf90b 100644 --- a/dependency-check-cli/xref-test/index.html +++ b/dependency-check-cli/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Command Line 1.3.6 Reference + Dependency-Check Command Line 1.4.0 Reference diff --git a/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-frame.html b/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-frame.html index da845dfde..94b087be3 100644 --- a/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-frame.html +++ b/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-summary.html b/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-summary.html index 8a8bb684f..9b1fe3dc1 100644 --- a/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-cli/xref-test/overview-frame.html b/dependency-check-cli/xref-test/overview-frame.html index 8875adeb3..6b5043647 100644 --- a/dependency-check-cli/xref-test/overview-frame.html +++ b/dependency-check-cli/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.3.6 Reference + Dependency-Check Command Line 1.4.0 Reference diff --git a/dependency-check-cli/xref-test/overview-summary.html b/dependency-check-cli/xref-test/overview-summary.html index b129042bf..c3857e7bb 100644 --- a/dependency-check-cli/xref-test/overview-summary.html +++ b/dependency-check-cli/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.3.6 Reference + Dependency-Check Command Line 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Command Line 1.3.6 Reference

      +

      Dependency-Check Command Line 1.4.0 Reference

      diff --git a/dependency-check-cli/xref/index.html b/dependency-check-cli/xref/index.html index fd5c36ab1..314aaf90b 100644 --- a/dependency-check-cli/xref/index.html +++ b/dependency-check-cli/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Command Line 1.3.6 Reference + Dependency-Check Command Line 1.4.0 Reference diff --git a/dependency-check-cli/xref/org/owasp/dependencycheck/App.html b/dependency-check-cli/xref/org/owasp/dependencycheck/App.html index 61f7466a9..06ae04ae2 100644 --- a/dependency-check-cli/xref/org/owasp/dependencycheck/App.html +++ b/dependency-check-cli/xref/org/owasp/dependencycheck/App.html @@ -288,166 +288,168 @@ 280final String cveBase12 = cli.getBaseCve12Url(); 281final String cveBase20 = cli.getBaseCve20Url(); 282final Integer cveValidForHours = cli.getCveValidForHours(); -283 -284if (propertiesFile != null) { -285try { -286 Settings.mergeProperties(propertiesFile); -287 } catch (FileNotFoundException ex) { -288 LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath()); -289 LOGGER.debug("", ex); -290 } catch (IOException ex) { -291 LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath()); -292 LOGGER.debug("", ex); -293 } -294 } -295// We have to wait until we've merged the properties before attempting to set whether we use -296// the proxy for Nexus since it could be disabled in the properties, but not explicitly stated -297// on the command line -298finalboolean nexusUsesProxy = cli.isNexusUsesProxy(); -299if (dataDirectory != null) { -300 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -301 } elseif (System.getProperty("basedir") != null) { -302final File dataDir = new File(System.getProperty("basedir"), "data"); -303 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -304 } else { -305final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -306final File base = jarPath.getParentFile(); -307final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -308final File dataDir = new File(base, sub); -309 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -310 } -311 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -312 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); -313 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); -314 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser); -315 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass); -316 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -317 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -318 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -319 -320//File Type Analyzer Settings -321 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); -322 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); -323 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); -324 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled()); -325 Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled()); -326 Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled()); -327 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled()); -328 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled()); -329 Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled()); -330 Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); -331 Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled()); -332 Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled()); -333 Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled()); -334 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled()); -335 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled()); -336 -337 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit()); -338 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -339 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -340 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -341 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -342 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -343 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -344 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -345 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); -346 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -347if (cveBase12 != null && !cveBase12.isEmpty()) { -348 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12); -349 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20); -350 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12); -351 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20); -352 } -353 } -354 -355/** -356 * Creates a file appender and adds it to logback. -357 * -358 * @param verboseLog the path to the verbose log file -359 */ -360privatevoid prepareLogger(String verboseLog) { -361final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); -362final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); -363 -364final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); -365 encoder.setPattern("%d %C:%L%n%-5level - %msg%n"); -366 encoder.setContext(context); -367 encoder.start(); -368final FileAppender fa = new FileAppender(); -369 fa.setAppend(true); -370 fa.setEncoder(encoder); -371 fa.setContext(context); -372 fa.setFile(verboseLog); -373final File f = new File(verboseLog); -374 String name = f.getName(); -375finalint i = name.lastIndexOf('.'); -376if (i > 1) { -377 name = name.substring(0, i); -378 } -379 fa.setName(name); -380 fa.start(); -381final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); -382 rootLogger.addAppender(fa); -383 } -384 -385/** -386 * Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style -387 * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first * -388 * or ?). -389 * -390 * @param path the path to canonicalize -391 * @return the canonical path -392 */ -393protected String ensureCanonicalPath(String path) { -394 String basePath = null; -395 String wildCards = null; -396final String file = path.replace('\\', '/'); -397if (file.contains("*") || file.contains("?")) { -398 -399int pos = getLastFileSeparator(file); -400if (pos < 0) { -401return file; -402 } -403 pos += 1; -404 basePath = file.substring(0, pos); -405 wildCards = file.substring(pos); -406 } else { -407 basePath = file; -408 } -409 -410 File f = new File(basePath); -411try { -412 f = f.getCanonicalFile(); -413if (wildCards != null) { -414 f = new File(f, wildCards); -415 } -416 } catch (IOException ex) { -417 LOGGER.warn("Invalid path '{}' was provided.", path); -418 LOGGER.debug("Invalid path provided", ex); -419 } -420return f.getAbsolutePath().replace('\\', '/'); -421 } -422 -423/** -424 * Returns the position of the last file separator. -425 * -426 * @param file a file path -427 * @return the position of the last file separator -428 */ -429privateint getLastFileSeparator(String file) { -430if (file.contains("*") || file.contains("?")) { -431int p1 = file.indexOf('*'); -432int p2 = file.indexOf('?'); -433 p1 = p1 > 0 ? p1 : file.length(); -434 p2 = p2 > 0 ? p2 : file.length(); -435int pos = p1 < p2 ? p1 : p2; -436 pos = file.lastIndexOf('/', pos); -437return pos; -438 } else { -439return file.lastIndexOf('/'); -440 } -441 } -442 } +283finalboolean experimentalEnabled = cli.isExperimentalEnabled(); +284 +285if (propertiesFile != null) { +286try { +287 Settings.mergeProperties(propertiesFile); +288 } catch (FileNotFoundException ex) { +289 LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath()); +290 LOGGER.debug("", ex); +291 } catch (IOException ex) { +292 LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath()); +293 LOGGER.debug("", ex); +294 } +295 } +296// We have to wait until we've merged the properties before attempting to set whether we use +297// the proxy for Nexus since it could be disabled in the properties, but not explicitly stated +298// on the command line +299finalboolean nexusUsesProxy = cli.isNexusUsesProxy(); +300if (dataDirectory != null) { +301 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +302 } elseif (System.getProperty("basedir") != null) { +303final File dataDir = new File(System.getProperty("basedir"), "data"); +304 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +305 } else { +306final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +307final File base = jarPath.getParentFile(); +308final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +309final File dataDir = new File(base, sub); +310 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +311 } +312 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +313 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); +314 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); +315 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser); +316 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass); +317 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +318 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +319 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +320 +321//File Type Analyzer Settings +322 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled); +323 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); +324 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); +325 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); +326 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled()); +327 Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled()); +328 Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled()); +329 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled()); +330 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled()); +331 Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled()); +332 Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); +333 Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled()); +334 Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled()); +335 Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled()); +336 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled()); +337 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled()); +338 +339 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit()); +340 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +341 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +342 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +343 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +344 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +345 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +346 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +347 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); +348 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +349if (cveBase12 != null && !cveBase12.isEmpty()) { +350 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12); +351 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20); +352 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12); +353 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20); +354 } +355 } +356 +357/** +358 * Creates a file appender and adds it to logback. +359 * +360 * @param verboseLog the path to the verbose log file +361 */ +362privatevoid prepareLogger(String verboseLog) { +363final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); +364final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); +365 +366final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); +367 encoder.setPattern("%d %C:%L%n%-5level - %msg%n"); +368 encoder.setContext(context); +369 encoder.start(); +370final FileAppender fa = new FileAppender(); +371 fa.setAppend(true); +372 fa.setEncoder(encoder); +373 fa.setContext(context); +374 fa.setFile(verboseLog); +375final File f = new File(verboseLog); +376 String name = f.getName(); +377finalint i = name.lastIndexOf('.'); +378if (i > 1) { +379 name = name.substring(0, i); +380 } +381 fa.setName(name); +382 fa.start(); +383final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); +384 rootLogger.addAppender(fa); +385 } +386 +387/** +388 * Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style +389 * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first * +390 * or ?). +391 * +392 * @param path the path to canonicalize +393 * @return the canonical path +394 */ +395protected String ensureCanonicalPath(String path) { +396 String basePath = null; +397 String wildCards = null; +398final String file = path.replace('\\', '/'); +399if (file.contains("*") || file.contains("?")) { +400 +401int pos = getLastFileSeparator(file); +402if (pos < 0) { +403return file; +404 } +405 pos += 1; +406 basePath = file.substring(0, pos); +407 wildCards = file.substring(pos); +408 } else { +409 basePath = file; +410 } +411 +412 File f = new File(basePath); +413try { +414 f = f.getCanonicalFile(); +415if (wildCards != null) { +416 f = new File(f, wildCards); +417 } +418 } catch (IOException ex) { +419 LOGGER.warn("Invalid path '{}' was provided.", path); +420 LOGGER.debug("Invalid path provided", ex); +421 } +422return f.getAbsolutePath().replace('\\', '/'); +423 } +424 +425/** +426 * Returns the position of the last file separator. +427 * +428 * @param file a file path +429 * @return the position of the last file separator +430 */ +431privateint getLastFileSeparator(String file) { +432if (file.contains("*") || file.contains("?")) { +433int p1 = file.indexOf('*'); +434int p2 = file.indexOf('?'); +435 p1 = p1 > 0 ? p1 : file.length(); +436 p2 = p2 > 0 ? p2 : file.length(); +437int pos = p1 < p2 ? p1 : p2; +438 pos = file.lastIndexOf('/', pos); +439return pos; +440 } else { +441return file.lastIndexOf('/'); +442 } +443 } +444 }
      diff --git a/dependency-check-cli/xref/org/owasp/dependencycheck/CliParser.html b/dependency-check-cli/xref/org/owasp/dependencycheck/CliParser.html index a03826056..3305f4a91 100644 --- a/dependency-check-cli/xref/org/owasp/dependencycheck/CliParser.html +++ b/dependency-check-cli/xref/org/owasp/dependencycheck/CliParser.html @@ -66,1248 +66,1335 @@ 58 * Parses the arguments passed in and captures the results for later use.59 *60 * @param args the command line arguments -61 * @throws FileNotFoundException is thrown when a 'file' argument does not point to a file that exists. -62 * @throws ParseException is thrown when a Parse Exception occurs. -63 */ -64publicvoid parse(String[] args) throws FileNotFoundException, ParseException { -65 line = parseArgs(args); -66 -67if (line != null) { -68 validateArgs(); -69 } -70 } -71 -72/** -73 * Parses the command line arguments. -74 * -75 * @param args the command line arguments -76 * @return the results of parsing the command line arguments -77 * @throws ParseException if the arguments are invalid -78 */ -79private CommandLine parseArgs(String[] args) throws ParseException { -80final CommandLineParser parser = new DefaultParser(); -81final Options options = createCommandLineOptions(); -82return parser.parse(options, args); -83 } -84 -85/** -86 * Validates that the command line arguments are valid. -87 * -88 * @throws FileNotFoundException if there is a file specified by either the SCAN or CPE command line arguments that does not -89 * exist. -90 * @throws ParseException is thrown if there is an exception parsing the command line. -91 */ -92privatevoid validateArgs() throws FileNotFoundException, ParseException { -93if (isUpdateOnly() || isRunScan()) { -94final String value = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS); -95if (value != null) { -96try { -97finalint i = Integer.parseInt(value); -98if (i < 0) { -99thrownew ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0."); -100 } -101 } catch (NumberFormatException ex) { -102thrownew ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0."); -103 } -104 } -105 } -106if (isRunScan()) { -107 validatePathExists(getScanFiles(), ARGUMENT.SCAN); -108 validatePathExists(getReportDirectory(), ARGUMENT.OUT); -109if (getPathToMono() != null) { -110 validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO); -111 } -112if (!line.hasOption(ARGUMENT.APP_NAME) && !line.hasOption(ARGUMENT.PROJECT)) { -113thrownew ParseException("Missing '" + ARGUMENT.PROJECT + "' argument; the scan cannot be run without the an project name."); -114 } -115if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) { -116final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT); -117try { -118 Format.valueOf(format); -119 } catch (IllegalArgumentException ex) { -120final String msg = String.format("An invalid 'format' of '%s' was specified. " -121 + "Supported output formats are XML, HTML, VULN, or ALL", format); -122thrownew ParseException(msg); -123 } -124 } -125if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null) -126 && (getBaseCve12Url() == null || getBaseCve20Url() == null || getModifiedCve12Url() == null || getModifiedCve20Url() == null)) { -127final String msg = "If one of the CVE URLs is specified they must all be specified; please add the missing CVE URL."; -128thrownew ParseException(msg); -129 } -130if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) { -131try { -132finalint i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH)); -133if (i < 0) { -134thrownew ParseException("Symbolic Link Depth (symLink) must be greater than zero."); -135 } -136 } catch (NumberFormatException ex) { -137thrownew ParseException("Symbolic Link Depth (symLink) is not a number."); -138 } -139 } -140 } -141 } -142 -143/** -144 * Validates whether or not the path(s) points at a file that exists; if the path(s) does not point to an existing file a -145 * FileNotFoundException is thrown. -146 * -147 * @param paths the paths to validate if they exists -148 * @param optType the option being validated (e.g. scan, out, etc.) -149 * @throws FileNotFoundException is thrown if one of the paths being validated does not exist. -150 */ -151privatevoid validatePathExists(String[] paths, String optType) throws FileNotFoundException { -152for (String path : paths) { -153 validatePathExists(path, optType); -154 } -155 } -156 -157/** -158 * Validates whether or not the path points at a file that exists; if the path does not point to an existing file a -159 * FileNotFoundException is thrown. -160 * -161 * @param path the paths to validate if they exists -162 * @param argumentName the argument being validated (e.g. scan, out, etc.) -163 * @throws FileNotFoundException is thrown if the path being validated does not exist. -164 */ -165privatevoid validatePathExists(String path, String argumentName) throws FileNotFoundException { -166if (path == null) { -167 isValid = false; -168final String msg = String.format("Invalid '%s' argument: null", argumentName); -169thrownew FileNotFoundException(msg); -170 } elseif (!path.contains("*") && !path.contains("?")) { -171 File f = new File(path); -172if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) { -173final String checkPath = path.toLowerCase(); -174if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) { -175if (f.getParentFile() == null) { -176 f = new File(".", path); -177 } -178if (!f.getParentFile().isDirectory()) { -179 isValid = false; -180final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); -181thrownew FileNotFoundException(msg); -182 } -183 } -184 } else { -185if (!f.exists()) { -186 isValid = false; -187final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); -188thrownew FileNotFoundException(msg); +61 * @throws FileNotFoundException is thrown when a 'file' argument does not +62 * point to a file that exists. +63 * @throws ParseException is thrown when a Parse Exception occurs. +64 */ +65publicvoid parse(String[] args) throws FileNotFoundException, ParseException { +66 line = parseArgs(args); +67 +68if (line != null) { +69 validateArgs(); +70 } +71 } +72 +73/** +74 * Parses the command line arguments. +75 * +76 * @param args the command line arguments +77 * @return the results of parsing the command line arguments +78 * @throws ParseException if the arguments are invalid +79 */ +80private CommandLine parseArgs(String[] args) throws ParseException { +81final CommandLineParser parser = new DefaultParser(); +82final Options options = createCommandLineOptions(); +83return parser.parse(options, args); +84 } +85 +86/** +87 * Validates that the command line arguments are valid. +88 * +89 * @throws FileNotFoundException if there is a file specified by either the +90 * SCAN or CPE command line arguments that does not exist. +91 * @throws ParseException is thrown if there is an exception parsing the +92 * command line. +93 */ +94privatevoid validateArgs() throws FileNotFoundException, ParseException { +95if (isUpdateOnly() || isRunScan()) { +96final String value = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS); +97if (value != null) { +98try { +99finalint i = Integer.parseInt(value); +100if (i < 0) { +101thrownew ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0."); +102 } +103 } catch (NumberFormatException ex) { +104thrownew ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0."); +105 } +106 } +107 } +108if (isRunScan()) { +109 validatePathExists(getScanFiles(), ARGUMENT.SCAN); +110 validatePathExists(getReportDirectory(), ARGUMENT.OUT); +111if (getPathToMono() != null) { +112 validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO); +113 } +114if (!line.hasOption(ARGUMENT.APP_NAME) && !line.hasOption(ARGUMENT.PROJECT)) { +115thrownew ParseException("Missing '" + ARGUMENT.PROJECT + "' argument; the scan cannot be run without the an project name."); +116 } +117if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) { +118final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT); +119try { +120 Format.valueOf(format); +121 } catch (IllegalArgumentException ex) { +122final String msg = String.format("An invalid 'format' of '%s' was specified. " +123 + "Supported output formats are XML, HTML, VULN, or ALL", format); +124thrownew ParseException(msg); +125 } +126 } +127if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null) +128 && (getBaseCve12Url() == null || getBaseCve20Url() == null || getModifiedCve12Url() == null || getModifiedCve20Url() == null)) { +129final String msg = "If one of the CVE URLs is specified they must all be specified; please add the missing CVE URL."; +130thrownew ParseException(msg); +131 } +132if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) { +133try { +134finalint i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH)); +135if (i < 0) { +136thrownew ParseException("Symbolic Link Depth (symLink) must be greater than zero."); +137 } +138 } catch (NumberFormatException ex) { +139thrownew ParseException("Symbolic Link Depth (symLink) is not a number."); +140 } +141 } +142 } +143 } +144 +145/** +146 * Validates whether or not the path(s) points at a file that exists; if the +147 * path(s) does not point to an existing file a FileNotFoundException is +148 * thrown. +149 * +150 * @param paths the paths to validate if they exists +151 * @param optType the option being validated (e.g. scan, out, etc.) +152 * @throws FileNotFoundException is thrown if one of the paths being +153 * validated does not exist. +154 */ +155privatevoid validatePathExists(String[] paths, String optType) throws FileNotFoundException { +156for (String path : paths) { +157 validatePathExists(path, optType); +158 } +159 } +160 +161/** +162 * Validates whether or not the path points at a file that exists; if the +163 * path does not point to an existing file a FileNotFoundException is +164 * thrown. +165 * +166 * @param path the paths to validate if they exists +167 * @param argumentName the argument being validated (e.g. scan, out, etc.) +168 * @throws FileNotFoundException is thrown if the path being validated does +169 * not exist. +170 */ +171privatevoid validatePathExists(String path, String argumentName) throws FileNotFoundException { +172if (path == null) { +173 isValid = false; +174final String msg = String.format("Invalid '%s' argument: null", argumentName); +175thrownew FileNotFoundException(msg); +176 } elseif (!path.contains("*") && !path.contains("?")) { +177 File f = new File(path); +178if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) { +179final String checkPath = path.toLowerCase(); +180if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) { +181if (f.getParentFile() == null) { +182 f = new File(".", path); +183 } +184if (!f.getParentFile().isDirectory()) { +185 isValid = false; +186final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); +187thrownew FileNotFoundException(msg); +188 } 189 } -190 } -191 } elseif (path.startsWith("//") || path.startsWith("\\\\")) { -192 isValid = false; -193final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path); -194thrownew FileNotFoundException(msg); -195 } -196 } -197 -198/** -199 * Generates an Options collection that is used to parse the command line and to display the help message. -200 * -201 * @return the command line options used for parsing the command line -202 */ -203 @SuppressWarnings("static-access") -204private Options createCommandLineOptions() { -205final Options options = new Options(); -206 addStandardOptions(options); -207 addAdvancedOptions(options); -208 addDeprecatedOptions(options); -209return options; -210 } -211 -212/** -213 * Adds the standard command line options to the given options collection. -214 * -215 * @param options a collection of command line arguments -216 * @throws IllegalArgumentException thrown if there is an exception -217 */ -218 @SuppressWarnings("static-access") -219privatevoid addStandardOptions(final Options options) throws IllegalArgumentException { -220final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false, -221"Print this message."); -222 -223final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP) -224 .desc("Print the advanced help message.").build(); -225 -226final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION, -227 false, "Print the version information."); -228 -229final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE, -230 false, "Disables the automatic updating of the CPE data."); -231 -232final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT) -233 .desc("The name of the project being scanned. This is a required argument.") -234 .build(); -235 -236final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN) -237 .desc("The path to scan - this option can be specified multiple times. Ant style" -238 + " paths are supported (e.g. path/**/*.jar).") +190 } elseif (!f.exists()) { +191 isValid = false; +192final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); +193thrownew FileNotFoundException(msg); +194 } +195 } elseif (path.startsWith("//") || path.startsWith("\\\\")) { +196 isValid = false; +197final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path); +198thrownew FileNotFoundException(msg); +199 } +200 } +201 +202/** +203 * Generates an Options collection that is used to parse the command line +204 * and to display the help message. +205 * +206 * @return the command line options used for parsing the command line +207 */ +208 @SuppressWarnings("static-access") +209private Options createCommandLineOptions() { +210final Options options = new Options(); +211 addStandardOptions(options); +212 addAdvancedOptions(options); +213 addDeprecatedOptions(options); +214return options; +215 } +216 +217/** +218 * Adds the standard command line options to the given options collection. +219 * +220 * @param options a collection of command line arguments +221 * @throws IllegalArgumentException thrown if there is an exception +222 */ +223 @SuppressWarnings("static-access") +224privatevoid addStandardOptions(final Options options) throws IllegalArgumentException { +225final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false, +226"Print this message."); +227 +228final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP) +229 .desc("Print the advanced help message.").build(); +230 +231final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION, +232 false, "Print the version information."); +233 +234final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE, +235 false, "Disables the automatic updating of the CPE data."); +236 +237final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT) +238 .desc("The name of the project being scanned. This is a required argument.") 239 .build(); 240 -241final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE) -242 .desc("Specify and exclusion pattern. This option can be specified multiple times" -243 + " and it accepts Ant style excludsions.") +241final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN) +242 .desc("The path to scan - this option can be specified multiple times. Ant style" +243 + " paths are supported (e.g. path/**/*.jar).") 244 .build(); 245 -246final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP) -247 .desc("A property file to load.") -248 .build(); -249 -250final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT) -251 .desc("The folder to write reports to. This defaults to the current directory. " -252 + "It is possible to set this to a specific file name if the format argument is not set to ALL.") +246final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE) +247 .desc("Specify and exclusion pattern. This option can be specified multiple times" +248 + " and it accepts Ant style excludsions.") +249 .build(); +250 +251final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP) +252 .desc("A property file to load.") 253 .build(); 254 -255final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT) -256 .desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.") -257 .build(); -258 -259final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG) -260 .desc("The file path to write verbose logging information.") -261 .build(); -262 -263final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH) -264 .desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.") -265 .build(); -266 -267final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE) -268 .desc("The file path to the suppression XML file.") -269 .build(); -270 -271final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS) -272 .desc("The number of hours to wait before checking for new updates from the NVD.") -273 .build(); -274 -275//This is an option group because it can be specified more then once. -276final OptionGroup og = new OptionGroup(); -277 og.addOption(path); -278 -279final OptionGroup exog = new OptionGroup(); -280 exog.addOption(excludes); -281 -282 options.addOptionGroup(og) -283 .addOptionGroup(exog) -284 .addOption(projectName) -285 .addOption(out) -286 .addOption(outputFormat) -287 .addOption(version) -288 .addOption(help) -289 .addOption(advancedHelp) -290 .addOption(noUpdate) -291 .addOption(symLinkDepth) -292 .addOption(props) -293 .addOption(verboseLog) -294 .addOption(suppressionFile) -295 .addOption(cveValidForHours); -296 } -297 -298/** -299 * Adds the advanced command line options to the given options collection. These are split out for purposes of being able to -300 * display two different help messages. -301 * -302 * @param options a collection of command line arguments -303 * @throws IllegalArgumentException thrown if there is an exception -304 */ -305 @SuppressWarnings("static-access") -306privatevoid addAdvancedOptions(final Options options) throws IllegalArgumentException { +255final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT) +256 .desc("The folder to write reports to. This defaults to the current directory. " +257 + "It is possible to set this to a specific file name if the format argument is not set to ALL.") +258 .build(); +259 +260final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT) +261 .desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.") +262 .build(); +263 +264final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG) +265 .desc("The file path to write verbose logging information.") +266 .build(); +267 +268final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH) +269 .desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.") +270 .build(); +271 +272final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE) +273 .desc("The file path to the suppression XML file.") +274 .build(); +275 +276final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS) +277 .desc("The number of hours to wait before checking for new updates from the NVD.") +278 .build(); +279 +280final Option experimentalEnabled = Option.builder().longOpt(ARGUMENT.EXPERIMENTAL) +281 .desc("Enables the experimental analzers.") +282 .build(); +283 +284//This is an option group because it can be specified more then once. +285final OptionGroup og = new OptionGroup(); +286 og.addOption(path); +287 +288final OptionGroup exog = new OptionGroup(); +289 exog.addOption(excludes); +290 +291 options.addOptionGroup(og) +292 .addOptionGroup(exog) +293 .addOption(projectName) +294 .addOption(out) +295 .addOption(outputFormat) +296 .addOption(version) +297 .addOption(help) +298 .addOption(advancedHelp) +299 .addOption(noUpdate) +300 .addOption(symLinkDepth) +301 .addOption(props) +302 .addOption(verboseLog) +303 .addOption(suppressionFile) +304 .addOption(cveValidForHours) +305 .addOption(experimentalEnabled); +306 } 307 -308final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12) -309 .desc("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ") -310 .build(); -311 -312final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20) -313 .desc("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.") -314 .build(); -315 -316final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12) -317 .desc("URL for the modified CVE 1.2.") -318 .build(); -319 -320final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20) -321 .desc("URL for the modified CVE 2.0.") -322 .build(); -323 -324final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY) -325 .desc("Only update the local NVD data cache; no scan will be executed.").build(); +308/** +309 * Adds the advanced command line options to the given options collection. +310 * These are split out for purposes of being able to display two different +311 * help messages. +312 * +313 * @param options a collection of command line arguments +314 * @throws IllegalArgumentException thrown if there is an exception +315 */ +316 @SuppressWarnings("static-access") +317privatevoid addAdvancedOptions(final Options options) throws IllegalArgumentException { +318 +319final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12) +320 .desc("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ") +321 .build(); +322 +323final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20) +324 .desc("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.") +325 .build(); 326 -327final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY) -328 .desc("The location of the H2 Database file. This option should generally not be set.") +327final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12) +328 .desc("URL for the modified CVE 1.2.") 329 .build(); 330 -331final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL) -332 .desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). " -333 + "If not set the Nexus Analyzer will be disabled.").build(); +331final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20) +332 .desc("URL for the modified CVE 2.0.") +333 .build(); 334 -335final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY) -336 .desc("Whether or not the configured proxy should be used when connecting to Nexus.") -337 .build(); -338 -339final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg() -340 .longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS) -341 .desc("A comma separated list of additional extensions to be scanned as ZIP files " -342 + "(ZIP, EAR, WAR are already treated as zip files)").build(); -343 -344final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO) -345 .desc("The path to Mono for .NET Assembly analysis on non-windows systems.") -346 .build(); -347 -348final Option pathToBundleAudit = Option.builder().argName("path").hasArg() -349 .longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT) -350 .desc("The path to bundle-audit for Gem bundle analysis.").build(); -351 -352final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg() -353 .longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.") -354 .build(); -355 -356final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER) -357 .desc("The proxy server to use when downloading resources.").build(); +335final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY) +336 .desc("Only update the local NVD data cache; no scan will be executed.").build(); +337 +338final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY) +339 .desc("The location of the H2 Database file. This option should generally not be set.") +340 .build(); +341 +342final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL) +343 .desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). " +344 + "If not set the Nexus Analyzer will be disabled.").build(); +345 +346final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY) +347 .desc("Whether or not the configured proxy should be used when connecting to Nexus.") +348 .build(); +349 +350final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg() +351 .longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS) +352 .desc("A comma separated list of additional extensions to be scanned as ZIP files " +353 + "(ZIP, EAR, WAR are already treated as zip files)").build(); +354 +355final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO) +356 .desc("The path to Mono for .NET Assembly analysis on non-windows systems.") +357 .build(); 358 -359final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT) -360 .desc("The proxy port to use when downloading resources.").build(); -361 -362final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME) -363 .desc("The proxy username to use when downloading resources.").build(); -364 -365final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD) -366 .desc("The proxy password to use when downloading resources.").build(); -367 -368final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING) -369 .desc("The connection string to the database.").build(); -370 -371final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME) -372 .desc("The username used to connect to the database.").build(); -373 -374final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD) -375 .desc("The password for connecting to the database.").build(); -376 -377final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER) -378 .desc("The database driver name.").build(); -379 -380final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH) -381 .desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.") -382 .build(); -383 -384final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR) -385 .desc("Disable the Jar Analyzer.").build(); -386 -387final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE) -388 .desc("Disable the Archive Analyzer.").build(); -389 -390final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC) -391 .desc("Disable the Nuspec Analyzer.").build(); -392 -393final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY) -394 .desc("Disable the .NET Assembly Analyzer.").build(); -395 -396final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST) -397 .desc("Disable the Python Distribution Analyzer.").build(); -398 -399final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG) -400 .desc("Disable the Python Package Analyzer.").build(); -401 -402final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER) -403 .desc("Disable the PHP Composer Analyzer.").build(); -404 -405final Option disableAutoconfAnalyzer = Option.builder() -406 .longOpt(ARGUMENT.DISABLE_AUTOCONF) -407 .desc("Disable the Autoconf Analyzer.").build(); -408 -409final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL) -410 .desc("Disable the OpenSSL Analyzer.").build(); -411final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE) -412 .desc("Disable the Cmake Analyzer.").build(); -413 -414final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL) -415 .desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable " -416 + "the Nexus Analyzer.").build(); -417 -418final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS) -419 .desc("Disable the Nexus Analyzer.").build(); -420 -421final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD) -422 .desc("Purges the local NVD data cache") -423 .build(); +359final Option pathToBundleAudit = Option.builder().argName("path").hasArg() +360 .longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT) +361 .desc("The path to bundle-audit for Gem bundle analysis.").build(); +362 +363final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg() +364 .longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.") +365 .build(); +366 +367final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER) +368 .desc("The proxy server to use when downloading resources.").build(); +369 +370final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT) +371 .desc("The proxy port to use when downloading resources.").build(); +372 +373final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME) +374 .desc("The proxy username to use when downloading resources.").build(); +375 +376final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD) +377 .desc("The proxy password to use when downloading resources.").build(); +378 +379final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING) +380 .desc("The connection string to the database.").build(); +381 +382final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME) +383 .desc("The username used to connect to the database.").build(); +384 +385final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD) +386 .desc("The password for connecting to the database.").build(); +387 +388final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER) +389 .desc("The database driver name.").build(); +390 +391final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH) +392 .desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.") +393 .build(); +394 +395final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR) +396 .desc("Disable the Jar Analyzer.").build(); +397 +398final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE) +399 .desc("Disable the Archive Analyzer.").build(); +400 +401final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC) +402 .desc("Disable the Nuspec Analyzer.").build(); +403 +404final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY) +405 .desc("Disable the .NET Assembly Analyzer.").build(); +406 +407final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST) +408 .desc("Disable the Python Distribution Analyzer.").build(); +409 +410final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG) +411 .desc("Disable the Python Package Analyzer.").build(); +412 +413final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER) +414 .desc("Disable the PHP Composer Analyzer.").build(); +415 +416final Option disableAutoconfAnalyzer = Option.builder() +417 .longOpt(ARGUMENT.DISABLE_AUTOCONF) +418 .desc("Disable the Autoconf Analyzer.").build(); +419 +420final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL) +421 .desc("Disable the OpenSSL Analyzer.").build(); +422final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE) +423 .desc("Disable the Cmake Analyzer.").build(); 424 -425 options.addOption(updateOnly) -426 .addOption(cve12Base) -427 .addOption(cve20Base) -428 .addOption(cve12Modified) -429 .addOption(cve20Modified) -430 .addOption(proxyPort) -431 .addOption(proxyServer) -432 .addOption(proxyUsername) -433 .addOption(proxyPassword) -434 .addOption(connectionTimeout) -435 .addOption(connectionString) -436 .addOption(dbUser) -437 .addOption(data) -438 .addOption(dbPassword) -439 .addOption(dbDriver) -440 .addOption(dbDriverPath) -441 .addOption(disableJarAnalyzer) -442 .addOption(disableArchiveAnalyzer) -443 .addOption(disableAssemblyAnalyzer) -444 .addOption(pathToBundleAudit) -445 .addOption(disablePythonDistributionAnalyzer) -446 .addOption(disableCmakeAnalyzer) -447 .addOption(disablePythonPackageAnalyzer) -448 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS) -449 .desc("Disable the Ruby Gemspec Analyzer.").build()) -450 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT) -451 .desc("Disable the Ruby Bundler-Audit Analyzer.").build()) -452 .addOption(disableAutoconfAnalyzer) -453 .addOption(disableComposerAnalyzer) -454 .addOption(disableOpenSSLAnalyzer) -455 .addOption(disableNuspecAnalyzer) -456 .addOption(disableCentralAnalyzer) -457 .addOption(disableNexusAnalyzer) -458 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS) -459 .desc("Disable the Node.js Package Analyzer.").build()) -460 .addOption(nexusUrl) -461 .addOption(nexusUsesProxy) -462 .addOption(additionalZipExtensions) -463 .addOption(pathToMono) -464 .addOption(pathToBundleAudit) -465 .addOption(purge); -466 } -467 -468/** -469 * Adds the deprecated command line options to the given options collection. These are split out for purposes of not including -470 * them in the help message. We need to add the deprecated options so as not to break existing scripts. -471 * -472 * @param options a collection of command line arguments -473 * @throws IllegalArgumentException thrown if there is an exception -474 */ -475 @SuppressWarnings({"static-access", "deprecation"}) -476privatevoid addDeprecatedOptions(final Options options) throws IllegalArgumentException { -477 -478final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL) -479 .desc("The proxy url argument is deprecated, use proxyserver instead.") -480 .build(); -481final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME) -482 .desc("The name of the project being scanned.") -483 .build(); -484 -485 options.addOption(proxyServer); -486 options.addOption(appName); -487 } -488 -489/** -490 * Determines if the 'version' command line argument was passed in. -491 * -492 * @return whether or not the 'version' command line argument was passed in -493 */ -494publicboolean isGetVersion() { -495return (line != null) && line.hasOption(ARGUMENT.VERSION); -496 } +425final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL) +426 .desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable " +427 + "the Nexus Analyzer.").build(); +428 +429final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS) +430 .desc("Disable the Nexus Analyzer.").build(); +431 +432final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD) +433 .desc("Purges the local NVD data cache") +434 .build(); +435 +436 options.addOption(updateOnly) +437 .addOption(cve12Base) +438 .addOption(cve20Base) +439 .addOption(cve12Modified) +440 .addOption(cve20Modified) +441 .addOption(proxyPort) +442 .addOption(proxyServer) +443 .addOption(proxyUsername) +444 .addOption(proxyPassword) +445 .addOption(connectionTimeout) +446 .addOption(connectionString) +447 .addOption(dbUser) +448 .addOption(data) +449 .addOption(dbPassword) +450 .addOption(dbDriver) +451 .addOption(dbDriverPath) +452 .addOption(disableJarAnalyzer) +453 .addOption(disableArchiveAnalyzer) +454 .addOption(disableAssemblyAnalyzer) +455 .addOption(pathToBundleAudit) +456 .addOption(disablePythonDistributionAnalyzer) +457 .addOption(disableCmakeAnalyzer) +458 .addOption(disablePythonPackageAnalyzer) +459 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS) +460 .desc("Disable the Ruby Gemspec Analyzer.").build()) +461 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT) +462 .desc("Disable the Ruby Bundler-Audit Analyzer.").build()) +463 .addOption(disableAutoconfAnalyzer) +464 .addOption(disableComposerAnalyzer) +465 .addOption(disableOpenSSLAnalyzer) +466 .addOption(disableNuspecAnalyzer) +467 .addOption(disableCentralAnalyzer) +468 .addOption(disableNexusAnalyzer) +469 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS) +470 .desc("Disable the Node.js Package Analyzer.").build()) +471 .addOption(nexusUrl) +472 .addOption(nexusUsesProxy) +473 .addOption(additionalZipExtensions) +474 .addOption(pathToMono) +475 .addOption(pathToBundleAudit) +476 .addOption(purge); +477 } +478 +479/** +480 * Adds the deprecated command line options to the given options collection. +481 * These are split out for purposes of not including them in the help +482 * message. We need to add the deprecated options so as not to break +483 * existing scripts. +484 * +485 * @param options a collection of command line arguments +486 * @throws IllegalArgumentException thrown if there is an exception +487 */ +488 @SuppressWarnings({"static-access", "deprecation"}) +489privatevoid addDeprecatedOptions(final Options options) throws IllegalArgumentException { +490 +491final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL) +492 .desc("The proxy url argument is deprecated, use proxyserver instead.") +493 .build(); +494final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME) +495 .desc("The name of the project being scanned.") +496 .build(); 497 -498/** -499 * Determines if the 'help' command line argument was passed in. -500 * -501 * @return whether or not the 'help' command line argument was passed in -502 */ -503publicboolean isGetHelp() { -504return (line != null) && line.hasOption(ARGUMENT.HELP); -505 } -506 -507/** -508 * Determines if the 'scan' command line argument was passed in. -509 * -510 * @return whether or not the 'scan' command line argument was passed in -511 */ -512publicboolean isRunScan() { -513return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN); -514 } -515 -516/** -517 * Returns the symbolic link depth (how deeply symbolic links will be followed). -518 * -519 * @return the symbolic link depth -520 */ -521publicint getSymLinkDepth() { -522int value = 0; -523try { -524 value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0")); -525if (value < 0) { -526 value = 0; -527 } -528 } catch (NumberFormatException ex) { -529 LOGGER.debug("Symbolic link was not a number"); -530 } -531return value; -532 } -533 -534/** -535 * Returns true if the disableJar command line argument was specified. -536 * -537 * @return true if the disableJar command line argument was specified; otherwise false -538 */ -539publicboolean isJarDisabled() { -540return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR); -541 } -542 -543/** -544 * Returns true if the disableArchive command line argument was specified. -545 * -546 * @return true if the disableArchive command line argument was specified; otherwise false -547 */ -548publicboolean isArchiveDisabled() { -549return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE); -550 } -551 -552/** -553 * Returns true if the disableNuspec command line argument was specified. -554 * -555 * @return true if the disableNuspec command line argument was specified; otherwise false -556 */ -557publicboolean isNuspecDisabled() { -558return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC); -559 } -560 -561/** -562 * Returns true if the disableAssembly command line argument was specified. -563 * -564 * @return true if the disableAssembly command line argument was specified; otherwise false -565 */ -566publicboolean isAssemblyDisabled() { -567return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY); -568 } -569 -570/** -571 * Returns true if the disableBundleAudit command line argument was specified. -572 * -573 * @return true if the disableBundleAudit command line argument was specified; otherwise false -574 */ -575publicboolean isBundleAuditDisabled() { -576return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT); -577 } -578 -579/** -580 * Returns true if the disablePyDist command line argument was specified. -581 * -582 * @return true if the disablePyDist command line argument was specified; otherwise false +498 options.addOption(proxyServer); +499 options.addOption(appName); +500 } +501 +502/** +503 * Determines if the 'version' command line argument was passed in. +504 * +505 * @return whether or not the 'version' command line argument was passed in +506 */ +507publicboolean isGetVersion() { +508return (line != null) && line.hasOption(ARGUMENT.VERSION); +509 } +510 +511/** +512 * Determines if the 'help' command line argument was passed in. +513 * +514 * @return whether or not the 'help' command line argument was passed in +515 */ +516publicboolean isGetHelp() { +517return (line != null) && line.hasOption(ARGUMENT.HELP); +518 } +519 +520/** +521 * Determines if the 'scan' command line argument was passed in. +522 * +523 * @return whether or not the 'scan' command line argument was passed in +524 */ +525publicboolean isRunScan() { +526return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN); +527 } +528 +529/** +530 * Returns the symbolic link depth (how deeply symbolic links will be +531 * followed). +532 * +533 * @return the symbolic link depth +534 */ +535publicint getSymLinkDepth() { +536int value = 0; +537try { +538 value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0")); +539if (value < 0) { +540 value = 0; +541 } +542 } catch (NumberFormatException ex) { +543 LOGGER.debug("Symbolic link was not a number"); +544 } +545return value; +546 } +547 +548/** +549 * Returns true if the disableJar command line argument was specified. +550 * +551 * @return true if the disableJar command line argument was specified; +552 * otherwise false +553 */ +554publicboolean isJarDisabled() { +555return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR); +556 } +557 +558/** +559 * Returns true if the disableArchive command line argument was specified. +560 * +561 * @return true if the disableArchive command line argument was specified; +562 * otherwise false +563 */ +564publicboolean isArchiveDisabled() { +565return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE); +566 } +567 +568/** +569 * Returns true if the disableNuspec command line argument was specified. +570 * +571 * @return true if the disableNuspec command line argument was specified; +572 * otherwise false +573 */ +574publicboolean isNuspecDisabled() { +575return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC); +576 } +577 +578/** +579 * Returns true if the disableAssembly command line argument was specified. +580 * +581 * @return true if the disableAssembly command line argument was specified; +582 * otherwise false583 */ -584publicboolean isPythonDistributionDisabled() { -585return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST); +584publicboolean isAssemblyDisabled() { +585return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY); 586 } 587588/** -589 * Returns true if the disablePyPkg command line argument was specified. -590 * -591 * @return true if the disablePyPkg command line argument was specified; otherwise false -592 */ -593publicboolean isPythonPackageDisabled() { -594return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG); -595 } -596 -597/** -598 * Returns whether the Ruby gemspec analyzer is disabled. -599 * -600 * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line argument was specified; otherwise false -601 */ -602publicboolean isRubyGemspecDisabled() { -603return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS); -604 } -605 -606/** -607 * Returns true if the disableCmake command line argument was specified. -608 * -609 * @return true if the disableCmake command line argument was specified; otherwise false -610 */ -611publicboolean isCmakeDisabled() { -612return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE); -613 } -614 -615/** -616 * Returns true if the disableAutoconf command line argument was specified. -617 * -618 * @return true if the disableAutoconf command line argument was specified; otherwise false -619 */ -620publicboolean isAutoconfDisabled() { -621return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF); -622 } -623 -624/** -625 * Returns true if the disableComposer command line argument was specified. -626 * -627 * @return true if the disableComposer command line argument was specified; otherwise false -628 */ -629publicboolean isComposerDisabled() { -630return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER); -631 } -632 -633/** -634 * Returns true if the disableNexus command line argument was specified. -635 * -636 * @return true if the disableNexus command line argument was specified; otherwise false -637 */ -638publicboolean isNexusDisabled() { -639return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS); -640 } -641 -642/** -643 * Returns true if the disableOpenSSL command line argument was specified. -644 * -645 * @return true if the disableOpenSSL command line argument was specified; otherwise false -646 */ -647publicboolean isOpenSSLDisabled() { -648return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL); -649 } -650 -651/** -652 * Returns true if the disableNodeJS command line argument was specified. -653 * -654 * @return true if the disableNodeJS command line argument was specified; otherwise false -655 */ -656publicboolean isNodeJsDisabled() { -657return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS); -658 } -659 -660/** -661 * Returns true if the disableCentral command line argument was specified. -662 * -663 * @return true if the disableCentral command line argument was specified; otherwise false +589 * Returns true if the disableBundleAudit command line argument was +590 * specified. +591 * +592 * @return true if the disableBundleAudit command line argument was +593 * specified; otherwise false +594 */ +595publicboolean isBundleAuditDisabled() { +596return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT); +597 } +598 +599/** +600 * Returns true if the disablePyDist command line argument was specified. +601 * +602 * @return true if the disablePyDist command line argument was specified; +603 * otherwise false +604 */ +605publicboolean isPythonDistributionDisabled() { +606return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST); +607 } +608 +609/** +610 * Returns true if the disablePyPkg command line argument was specified. +611 * +612 * @return true if the disablePyPkg command line argument was specified; +613 * otherwise false +614 */ +615publicboolean isPythonPackageDisabled() { +616return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG); +617 } +618 +619/** +620 * Returns whether the Ruby gemspec analyzer is disabled. +621 * +622 * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line +623 * argument was specified; otherwise false +624 */ +625publicboolean isRubyGemspecDisabled() { +626return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS); +627 } +628 +629/** +630 * Returns true if the disableCmake command line argument was specified. +631 * +632 * @return true if the disableCmake command line argument was specified; +633 * otherwise false +634 */ +635publicboolean isCmakeDisabled() { +636return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE); +637 } +638 +639/** +640 * Returns true if the disableAutoconf command line argument was specified. +641 * +642 * @return true if the disableAutoconf command line argument was specified; +643 * otherwise false +644 */ +645publicboolean isAutoconfDisabled() { +646return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF); +647 } +648 +649/** +650 * Returns true if the disableComposer command line argument was specified. +651 * +652 * @return true if the disableComposer command line argument was specified; +653 * otherwise false +654 */ +655publicboolean isComposerDisabled() { +656return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER); +657 } +658 +659/** +660 * Returns true if the disableNexus command line argument was specified. +661 * +662 * @return true if the disableNexus command line argument was specified; +663 * otherwise false664 */ -665publicboolean isCentralDisabled() { -666return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL); +665publicboolean isNexusDisabled() { +666return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS); 667 } 668669/** -670 * Returns the url to the nexus server if one was specified. +670 * Returns true if the disableOpenSSL command line argument was specified.671 * -672 * @return the url to the nexus server; if none was specified this will return null; -673 */ -674public String getNexusUrl() { -675if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) { -676returnnull; -677 } else { -678return line.getOptionValue(ARGUMENT.NEXUS_URL); -679 } -680 } -681 -682/** -683 * Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is returned. -684 * -685 * @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false -686 */ -687publicboolean isNexusUsesProxy() { -688// If they didn't specify whether Nexus needs to use the proxy, we should -689// still honor the property if it's set. -690if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) { -691try { -692return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY); -693 } catch (InvalidSettingException ise) { -694returntrue; -695 } -696 } else { -697return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY)); -698 } -699 } -700 -701/** -702 * Displays the command line help message to the standard output. -703 */ -704publicvoid printHelp() { -705final HelpFormatter formatter = new HelpFormatter(); -706final Options options = new Options(); -707 addStandardOptions(options); -708if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) { -709 addAdvancedOptions(options); +672 * @return true if the disableOpenSSL command line argument was specified; +673 * otherwise false +674 */ +675publicboolean isOpenSSLDisabled() { +676return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL); +677 } +678 +679/** +680 * Returns true if the disableNodeJS command line argument was specified. +681 * +682 * @return true if the disableNodeJS command line argument was specified; +683 * otherwise false +684 */ +685publicboolean isNodeJsDisabled() { +686return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS); +687 } +688 +689/** +690 * Returns true if the disableCentral command line argument was specified. +691 * +692 * @return true if the disableCentral command line argument was specified; +693 * otherwise false +694 */ +695publicboolean isCentralDisabled() { +696return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL); +697 } +698 +699/** +700 * Returns the url to the nexus server if one was specified. +701 * +702 * @return the url to the nexus server; if none was specified this will +703 * return null; +704 */ +705public String getNexusUrl() { +706if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) { +707returnnull; +708 } else { +709return line.getOptionValue(ARGUMENT.NEXUS_URL); 710 } -711final String helpMsg = String.format("%n%s" -712 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. " -713 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n", -714 Settings.getString("application.name", "DependencyCheck"), -715 Settings.getString("application.name", "DependencyCheck")); -716 -717 formatter.printHelp(Settings.getString("application.name", "DependencyCheck"), -718 helpMsg, -719 options, -720"", -721true); -722 } -723 -724/** -725 * Retrieves the file command line parameter(s) specified for the 'scan' argument. -726 * -727 * @return the file paths specified on the command line for scan -728 */ -729public String[] getScanFiles() { -730return line.getOptionValues(ARGUMENT.SCAN); -731 } -732 -733/** -734 * Retrieves the list of excluded file patterns specified by the 'exclude' argument. -735 * -736 * @return the excluded file patterns -737 */ -738public String[] getExcludeList() { -739return line.getOptionValues(ARGUMENT.EXCLUDE); -740 } -741 -742/** -743 * Returns the directory to write the reports to specified on the command line. -744 * -745 * @return the path to the reports directory. -746 */ -747public String getReportDirectory() { -748return line.getOptionValue(ARGUMENT.OUT, "."); -749 } -750 -751/** -752 * Returns the path to Mono for .NET Assembly analysis on non-windows systems. -753 * -754 * @return the path to Mono -755 */ -756public String getPathToMono() { -757return line.getOptionValue(ARGUMENT.PATH_TO_MONO); -758 } -759 -760/** -761 * Returns the path to bundle-audit for Ruby bundle analysis. -762 * -763 * @return the path to Mono -764 */ -765public String getPathToBundleAudit() { -766return line.getOptionValue(ARGUMENT.PATH_TO_BUNDLE_AUDIT); -767 } -768 -769/** -770 * Returns the output format specified on the command line. Defaults to HTML if no format was specified. -771 * -772 * @return the output format name. -773 */ -774public String getReportFormat() { -775return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML"); -776 } -777 -778/** -779 * Returns the application name specified on the command line. +711 } +712 +713/** +714 * Returns true if the Nexus Analyzer should use the configured proxy to +715 * connect to Nexus; otherwise false is returned. +716 * +717 * @return true if the Nexus Analyzer should use the configured proxy to +718 * connect to Nexus; otherwise false +719 */ +720publicboolean isNexusUsesProxy() { +721// If they didn't specify whether Nexus needs to use the proxy, we should +722// still honor the property if it's set. +723if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) { +724try { +725return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY); +726 } catch (InvalidSettingException ise) { +727returntrue; +728 } +729 } else { +730return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY)); +731 } +732 } +733 +734/** +735 * Displays the command line help message to the standard output. +736 */ +737publicvoid printHelp() { +738final HelpFormatter formatter = new HelpFormatter(); +739final Options options = new Options(); +740 addStandardOptions(options); +741if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) { +742 addAdvancedOptions(options); +743 } +744final String helpMsg = String.format("%n%s" +745 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. " +746 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n", +747 Settings.getString("application.name", "DependencyCheck"), +748 Settings.getString("application.name", "DependencyCheck")); +749 +750 formatter.printHelp(Settings.getString("application.name", "DependencyCheck"), +751 helpMsg, +752 options, +753"", +754true); +755 } +756 +757/** +758 * Retrieves the file command line parameter(s) specified for the 'scan' +759 * argument. +760 * +761 * @return the file paths specified on the command line for scan +762 */ +763public String[] getScanFiles() { +764return line.getOptionValues(ARGUMENT.SCAN); +765 } +766 +767/** +768 * Retrieves the list of excluded file patterns specified by the 'exclude' +769 * argument. +770 * +771 * @return the excluded file patterns +772 */ +773public String[] getExcludeList() { +774return line.getOptionValues(ARGUMENT.EXCLUDE); +775 } +776 +777/** +778 * Returns the directory to write the reports to specified on the command +779 * line.780 * -781 * @return the application name. +781 * @return the path to the reports directory.782 */ -783public String getProjectName() { -784final String appName = line.getOptionValue(ARGUMENT.APP_NAME); -785 String name = line.getOptionValue(ARGUMENT.PROJECT); -786if (name == null && appName != null) { -787 name = appName; -788 LOGGER.warn("The '" + ARGUMENT.APP_NAME + "' argument should no longer be used; use '" + ARGUMENT.PROJECT + "' instead."); -789 } -790return name; -791 } -792 -793/** -794 * Returns the base URL for the CVE 1.2 XMl file. -795 * -796 * @return the URL to the CVE 1.2 XML file. -797 */ -798public String getBaseCve12Url() { -799return line.getOptionValue(ARGUMENT.CVE_BASE_12); -800 } -801 -802/** -803 * Returns the base URL for the CVE 2.0 XMl file. -804 * -805 * @return the URL to the CVE 2.0 XML file. -806 */ -807public String getBaseCve20Url() { -808return line.getOptionValue(ARGUMENT.CVE_BASE_20); -809 } -810 -811/** -812 * Returns the URL for the modified CVE 1.2 XMl file. -813 * -814 * @return the URL to the modified CVE 1.2 XML file. -815 */ -816public String getModifiedCve12Url() { -817return line.getOptionValue(ARGUMENT.CVE_MOD_12); -818 } -819 -820/** -821 * Returns the URL for the modified CVE 2.0 XMl file. -822 * -823 * @return the URL to the modified CVE 2.0 XML file. -824 */ -825public String getModifiedCve20Url() { -826return line.getOptionValue(ARGUMENT.CVE_MOD_20); -827 } -828 -829/** -830 * Returns the connection timeout. -831 * -832 * @return the connection timeout -833 */ -834public String getConnectionTimeout() { -835return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT); -836 } -837 -838/** -839 * Returns the proxy server. -840 * -841 * @return the proxy server -842 */ -843 @SuppressWarnings("deprecation") -844public String getProxyServer() { -845 -846 String server = line.getOptionValue(ARGUMENT.PROXY_SERVER); -847if (server == null) { -848 server = line.getOptionValue(ARGUMENT.PROXY_URL); -849if (server != null) { -850 LOGGER.warn("An old command line argument 'proxyurl' was detected; use proxyserver instead"); -851 } -852 } -853return server; -854 } -855 -856/** -857 * Returns the proxy port. -858 * -859 * @return the proxy port -860 */ -861public String getProxyPort() { -862return line.getOptionValue(ARGUMENT.PROXY_PORT); -863 } -864 -865/** -866 * Returns the proxy username. -867 * -868 * @return the proxy username -869 */ -870public String getProxyUsername() { -871return line.getOptionValue(ARGUMENT.PROXY_USERNAME); -872 } -873 -874/** -875 * Returns the proxy password. -876 * -877 * @return the proxy password -878 */ -879public String getProxyPassword() { -880return line.getOptionValue(ARGUMENT.PROXY_PASSWORD); -881 } -882 -883/** -884 * Get the value of dataDirectory. -885 * -886 * @return the value of dataDirectory -887 */ -888public String getDataDirectory() { -889return line.getOptionValue(ARGUMENT.DATA_DIRECTORY); -890 } -891 -892/** -893 * Returns the properties file specified on the command line. -894 * -895 * @return the properties file specified on the command line -896 */ -897public File getPropertiesFile() { -898final String path = line.getOptionValue(ARGUMENT.PROP); -899if (path != null) { -900returnnew File(path); -901 } -902returnnull; -903 } -904 -905/** -906 * Returns the path to the verbose log file. -907 * -908 * @return the path to the verbose log file -909 */ -910public String getVerboseLog() { -911return line.getOptionValue(ARGUMENT.VERBOSE_LOG); -912 } -913 -914/** -915 * Returns the path to the suppression file. -916 * -917 * @return the path to the suppression file -918 */ -919public String getSuppressionFile() { -920return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE); -921 } -922 -923/** -924 * <p> -925 * Prints the manifest information to standard output.</p> -926 * <ul><li>Implementation-Title: ${pom.name}</li> -927 * <li>Implementation-Version: ${pom.version}</li></ul> -928 */ -929publicvoid printVersionInfo() { -930final String version = String.format("%s version %s", -931 Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"), -932 Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); -933 System.out.println(version); -934 } -935 -936/** -937 * Checks if the auto update feature has been disabled. If it has been disabled via the command line this will return false. -938 * -939 * @return <code>true</code> if auto-update is allowed; otherwise <code>false</code> -940 */ -941publicboolean isAutoUpdate() { -942return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE); -943 } -944 -945/** -946 * Checks if the update only flag has been set. -947 * -948 * @return <code>true</code> if the update only flag has been set; otherwise <code>false</code>. -949 */ -950publicboolean isUpdateOnly() { -951return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY); -952 } -953 -954/** -955 * Checks if the purge NVD flag has been set. -956 * -957 * @return <code>true</code> if the purge nvd flag has been set; otherwise <code>false</code>. -958 */ -959publicboolean isPurge() { -960return line != null && line.hasOption(ARGUMENT.PURGE_NVD); -961 } -962 -963/** -964 * Returns the database driver name if specified; otherwise null is returned. -965 * -966 * @return the database driver name if specified; otherwise null is returned -967 */ -968public String getDatabaseDriverName() { -969return line.getOptionValue(ARGUMENT.DB_DRIVER); -970 } -971 -972/** -973 * Returns the database driver path if specified; otherwise null is returned. -974 * -975 * @return the database driver name if specified; otherwise null is returned -976 */ -977public String getDatabaseDriverPath() { -978return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH); -979 } -980 -981/** -982 * Returns the database connection string if specified; otherwise null is returned. -983 * -984 * @return the database connection string if specified; otherwise null is returned -985 */ -986public String getConnectionString() { -987return line.getOptionValue(ARGUMENT.CONNECTION_STRING); -988 } -989 -990/** -991 * Returns the database database user name if specified; otherwise null is returned. -992 * -993 * @return the database database user name if specified; otherwise null is returned -994 */ -995public String getDatabaseUser() { -996return line.getOptionValue(ARGUMENT.DB_NAME); -997 } -998 -999/** -1000 * Returns the database database password if specified; otherwise null is returned. -1001 * -1002 * @return the database database password if specified; otherwise null is returned -1003 */ -1004public String getDatabasePassword() { -1005return line.getOptionValue(ARGUMENT.DB_PASSWORD); -1006 } -1007 -1008/** -1009 * Returns the additional Extensions if specified; otherwise null is returned. -1010 * -1011 * @return the additional Extensions; otherwise null is returned -1012 */ -1013public String getAdditionalZipExtensions() { -1014return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS); -1015 } -1016 -1017/** -1018 * Get the value of cveValidForHours. -1019 * -1020 * @return the value of cveValidForHours -1021 */ -1022public Integer getCveValidForHours() { -1023final String v = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS); -1024if (v != null) { -1025return Integer.parseInt(v); -1026 } -1027returnnull; -1028 } -1029 -1030/** -1031 * A collection of static final strings that represent the possible command line arguments. -1032 */ -1033publicstaticclassARGUMENT { -1034 -1035/** -1036 * The long CLI argument name specifying the directory/file to scan. -1037 */ -1038publicstaticfinal String SCAN = "scan"; -1039/** -1040 * The short CLI argument name specifying the directory/file to scan. -1041 */ -1042publicstaticfinal String SCAN_SHORT = "s"; -1043/** -1044 * The long CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. -1045 */ -1046publicstaticfinal String DISABLE_AUTO_UPDATE = "noupdate"; -1047/** -1048 * The short CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. -1049 */ -1050publicstaticfinal String DISABLE_AUTO_UPDATE_SHORT = "n"; -1051/** -1052 * The long CLI argument name specifying that only the update phase should be executed; no scan should be run. -1053 */ -1054publicstaticfinal String UPDATE_ONLY = "updateonly"; -1055/** -1056 * The long CLI argument name specifying that only the update phase should be executed; no scan should be run. -1057 */ -1058publicstaticfinal String PURGE_NVD = "purge"; -1059/** -1060 * The long CLI argument name specifying the directory to write the reports to. -1061 */ -1062publicstaticfinal String OUT = "out"; -1063/** -1064 * The short CLI argument name specifying the directory to write the reports to. -1065 */ -1066publicstaticfinal String OUT_SHORT = "o"; -1067/** -1068 * The long CLI argument name specifying the output format to write the reports to. -1069 */ -1070publicstaticfinal String OUTPUT_FORMAT = "format"; -1071/** -1072 * The short CLI argument name specifying the output format to write the reports to. -1073 */ -1074publicstaticfinal String OUTPUT_FORMAT_SHORT = "f"; -1075/** -1076 * The long CLI argument name specifying the name of the project to be scanned. -1077 */ -1078publicstaticfinal String PROJECT = "project"; -1079/** -1080 * The long CLI argument name specifying the name of the application to be scanned. -1081 * -1082 * @deprecated project should be used instead -1083 */ -1084 @Deprecated -1085publicstaticfinal String APP_NAME = "app"; -1086/** -1087 * The short CLI argument name specifying the name of the application to be scanned. -1088 * -1089 * @deprecated project should be used instead -1090 */ -1091 @Deprecated -1092publicstaticfinal String APP_NAME_SHORT = "a"; -1093/** -1094 * The long CLI argument name asking for help. -1095 */ -1096publicstaticfinal String HELP = "help"; -1097/** -1098 * The long CLI argument name asking for advanced help. -1099 */ -1100publicstaticfinal String ADVANCED_HELP = "advancedHelp"; -1101/** -1102 * The short CLI argument name asking for help. -1103 */ -1104publicstaticfinal String HELP_SHORT = "h"; -1105/** -1106 * The long CLI argument name asking for the version. +783public String getReportDirectory() { +784return line.getOptionValue(ARGUMENT.OUT, "."); +785 } +786 +787/** +788 * Returns the path to Mono for .NET Assembly analysis on non-windows +789 * systems. +790 * +791 * @return the path to Mono +792 */ +793public String getPathToMono() { +794return line.getOptionValue(ARGUMENT.PATH_TO_MONO); +795 } +796 +797/** +798 * Returns the path to bundle-audit for Ruby bundle analysis. +799 * +800 * @return the path to Mono +801 */ +802public String getPathToBundleAudit() { +803return line.getOptionValue(ARGUMENT.PATH_TO_BUNDLE_AUDIT); +804 } +805 +806/** +807 * Returns the output format specified on the command line. Defaults to HTML +808 * if no format was specified. +809 * +810 * @return the output format name. +811 */ +812public String getReportFormat() { +813return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML"); +814 } +815 +816/** +817 * Returns the application name specified on the command line. +818 * +819 * @return the application name. +820 */ +821public String getProjectName() { +822final String appName = line.getOptionValue(ARGUMENT.APP_NAME); +823 String name = line.getOptionValue(ARGUMENT.PROJECT); +824if (name == null && appName != null) { +825 name = appName; +826 LOGGER.warn("The '" + ARGUMENT.APP_NAME + "' argument should no longer be used; use '" + ARGUMENT.PROJECT + "' instead."); +827 } +828return name; +829 } +830 +831/** +832 * Returns the base URL for the CVE 1.2 XMl file. +833 * +834 * @return the URL to the CVE 1.2 XML file. +835 */ +836public String getBaseCve12Url() { +837return line.getOptionValue(ARGUMENT.CVE_BASE_12); +838 } +839 +840/** +841 * Returns the base URL for the CVE 2.0 XMl file. +842 * +843 * @return the URL to the CVE 2.0 XML file. +844 */ +845public String getBaseCve20Url() { +846return line.getOptionValue(ARGUMENT.CVE_BASE_20); +847 } +848 +849/** +850 * Returns the URL for the modified CVE 1.2 XMl file. +851 * +852 * @return the URL to the modified CVE 1.2 XML file. +853 */ +854public String getModifiedCve12Url() { +855return line.getOptionValue(ARGUMENT.CVE_MOD_12); +856 } +857 +858/** +859 * Returns the URL for the modified CVE 2.0 XMl file. +860 * +861 * @return the URL to the modified CVE 2.0 XML file. +862 */ +863public String getModifiedCve20Url() { +864return line.getOptionValue(ARGUMENT.CVE_MOD_20); +865 } +866 +867/** +868 * Returns the connection timeout. +869 * +870 * @return the connection timeout +871 */ +872public String getConnectionTimeout() { +873return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT); +874 } +875 +876/** +877 * Returns the proxy server. +878 * +879 * @return the proxy server +880 */ +881 @SuppressWarnings("deprecation") +882public String getProxyServer() { +883 +884 String server = line.getOptionValue(ARGUMENT.PROXY_SERVER); +885if (server == null) { +886 server = line.getOptionValue(ARGUMENT.PROXY_URL); +887if (server != null) { +888 LOGGER.warn("An old command line argument 'proxyurl' was detected; use proxyserver instead"); +889 } +890 } +891return server; +892 } +893 +894/** +895 * Returns the proxy port. +896 * +897 * @return the proxy port +898 */ +899public String getProxyPort() { +900return line.getOptionValue(ARGUMENT.PROXY_PORT); +901 } +902 +903/** +904 * Returns the proxy username. +905 * +906 * @return the proxy username +907 */ +908public String getProxyUsername() { +909return line.getOptionValue(ARGUMENT.PROXY_USERNAME); +910 } +911 +912/** +913 * Returns the proxy password. +914 * +915 * @return the proxy password +916 */ +917public String getProxyPassword() { +918return line.getOptionValue(ARGUMENT.PROXY_PASSWORD); +919 } +920 +921/** +922 * Get the value of dataDirectory. +923 * +924 * @return the value of dataDirectory +925 */ +926public String getDataDirectory() { +927return line.getOptionValue(ARGUMENT.DATA_DIRECTORY); +928 } +929 +930/** +931 * Returns the properties file specified on the command line. +932 * +933 * @return the properties file specified on the command line +934 */ +935public File getPropertiesFile() { +936final String path = line.getOptionValue(ARGUMENT.PROP); +937if (path != null) { +938returnnew File(path); +939 } +940returnnull; +941 } +942 +943/** +944 * Returns the path to the verbose log file. +945 * +946 * @return the path to the verbose log file +947 */ +948public String getVerboseLog() { +949return line.getOptionValue(ARGUMENT.VERBOSE_LOG); +950 } +951 +952/** +953 * Returns the path to the suppression file. +954 * +955 * @return the path to the suppression file +956 */ +957public String getSuppressionFile() { +958return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE); +959 } +960 +961/** +962 * <p> +963 * Prints the manifest information to standard output.</p> +964 * <ul><li>Implementation-Title: ${pom.name}</li> +965 * <li>Implementation-Version: ${pom.version}</li></ul> +966 */ +967publicvoid printVersionInfo() { +968final String version = String.format("%s version %s", +969 Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"), +970 Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); +971 System.out.println(version); +972 } +973 +974/** +975 * Checks if the auto update feature has been disabled. If it has been +976 * disabled via the command line this will return false. +977 * +978 * @return <code>true</code> if auto-update is allowed; otherwise +979 * <code>false</code> +980 */ +981publicboolean isAutoUpdate() { +982return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE); +983 } +984 +985/** +986 * Checks if the update only flag has been set. +987 * +988 * @return <code>true</code> if the update only flag has been set; otherwise +989 * <code>false</code>. +990 */ +991publicboolean isUpdateOnly() { +992return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY); +993 } +994 +995/** +996 * Checks if the purge NVD flag has been set. +997 * +998 * @return <code>true</code> if the purge nvd flag has been set; otherwise +999 * <code>false</code>. +1000 */ +1001publicboolean isPurge() { +1002return line != null && line.hasOption(ARGUMENT.PURGE_NVD); +1003 } +1004 +1005/** +1006 * Returns the database driver name if specified; otherwise null is +1007 * returned. +1008 * +1009 * @return the database driver name if specified; otherwise null is returned +1010 */ +1011public String getDatabaseDriverName() { +1012return line.getOptionValue(ARGUMENT.DB_DRIVER); +1013 } +1014 +1015/** +1016 * Returns the database driver path if specified; otherwise null is +1017 * returned. +1018 * +1019 * @return the database driver name if specified; otherwise null is returned +1020 */ +1021public String getDatabaseDriverPath() { +1022return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH); +1023 } +1024 +1025/** +1026 * Returns the database connection string if specified; otherwise null is +1027 * returned. +1028 * +1029 * @return the database connection string if specified; otherwise null is +1030 * returned +1031 */ +1032public String getConnectionString() { +1033return line.getOptionValue(ARGUMENT.CONNECTION_STRING); +1034 } +1035 +1036/** +1037 * Returns the database database user name if specified; otherwise null is +1038 * returned. +1039 * +1040 * @return the database database user name if specified; otherwise null is +1041 * returned +1042 */ +1043public String getDatabaseUser() { +1044return line.getOptionValue(ARGUMENT.DB_NAME); +1045 } +1046 +1047/** +1048 * Returns the database database password if specified; otherwise null is +1049 * returned. +1050 * +1051 * @return the database database password if specified; otherwise null is +1052 * returned +1053 */ +1054public String getDatabasePassword() { +1055return line.getOptionValue(ARGUMENT.DB_PASSWORD); +1056 } +1057 +1058/** +1059 * Returns the additional Extensions if specified; otherwise null is +1060 * returned. +1061 * +1062 * @return the additional Extensions; otherwise null is returned +1063 */ +1064public String getAdditionalZipExtensions() { +1065return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS); +1066 } +1067 +1068/** +1069 * Get the value of cveValidForHours. +1070 * +1071 * @return the value of cveValidForHours +1072 */ +1073public Integer getCveValidForHours() { +1074final String v = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS); +1075if (v != null) { +1076return Integer.parseInt(v); +1077 } +1078returnnull; +1079 } +1080 +1081/** +1082 * Returns true if the experimental analyzers are enabled. +1083 * +1084 * @return true if the experimental analyzers are enabled; otherwise false +1085 */ +1086publicboolean isExperimentalEnabled() { +1087return line.hasOption(ARGUMENT.EXPERIMENTAL); +1088 } +1089 +1090/** +1091 * A collection of static final strings that represent the possible command +1092 * line arguments. +1093 */ +1094publicstaticclassARGUMENT { +1095 +1096/** +1097 * The long CLI argument name specifying the directory/file to scan. +1098 */ +1099publicstaticfinal String SCAN = "scan"; +1100/** +1101 * The short CLI argument name specifying the directory/file to scan. +1102 */ +1103publicstaticfinal String SCAN_SHORT = "s"; +1104/** +1105 * The long CLI argument name specifying that the CPE/CVE/etc. data +1106 * should not be automatically updated.1107 */ -1108publicstaticfinal String VERSION_SHORT = "v"; +1108publicstaticfinal String DISABLE_AUTO_UPDATE = "noupdate"; 1109/** -1110 * The short CLI argument name asking for the version. -1111 */ -1112publicstaticfinal String VERSION = "version"; -1113/** -1114 * The CLI argument name indicating the proxy port. -1115 */ -1116publicstaticfinal String PROXY_PORT = "proxyport"; -1117/** -1118 * The CLI argument name indicating the proxy server. -1119 */ -1120publicstaticfinal String PROXY_SERVER = "proxyserver"; -1121/** -1122 * The CLI argument name indicating the proxy url. -1123 * -1124 * @deprecated use {@link #PROXY_SERVER} instead -1125 */ -1126 @Deprecated -1127publicstaticfinal String PROXY_URL = "proxyurl"; -1128/** -1129 * The CLI argument name indicating the proxy username. -1130 */ -1131publicstaticfinal String PROXY_USERNAME = "proxyuser"; -1132/** -1133 * The CLI argument name indicating the proxy password. -1134 */ -1135publicstaticfinal String PROXY_PASSWORD = "proxypass"; -1136/** -1137 * The short CLI argument name indicating the connection timeout. -1138 */ -1139publicstaticfinal String CONNECTION_TIMEOUT_SHORT = "c"; -1140/** -1141 * The CLI argument name indicating the connection timeout. +1110 * The short CLI argument name specifying that the CPE/CVE/etc. data +1111 * should not be automatically updated. +1112 */ +1113publicstaticfinal String DISABLE_AUTO_UPDATE_SHORT = "n"; +1114/** +1115 * The long CLI argument name specifying that only the update phase +1116 * should be executed; no scan should be run. +1117 */ +1118publicstaticfinal String UPDATE_ONLY = "updateonly"; +1119/** +1120 * The long CLI argument name specifying that only the update phase +1121 * should be executed; no scan should be run. +1122 */ +1123publicstaticfinal String PURGE_NVD = "purge"; +1124/** +1125 * The long CLI argument name specifying the directory to write the +1126 * reports to. +1127 */ +1128publicstaticfinal String OUT = "out"; +1129/** +1130 * The short CLI argument name specifying the directory to write the +1131 * reports to. +1132 */ +1133publicstaticfinal String OUT_SHORT = "o"; +1134/** +1135 * The long CLI argument name specifying the output format to write the +1136 * reports to. +1137 */ +1138publicstaticfinal String OUTPUT_FORMAT = "format"; +1139/** +1140 * The short CLI argument name specifying the output format to write the +1141 * reports to.1142 */ -1143publicstaticfinal String CONNECTION_TIMEOUT = "connectiontimeout"; +1143publicstaticfinal String OUTPUT_FORMAT_SHORT = "f"; 1144/** -1145 * The short CLI argument name for setting the location of an additional properties file. -1146 */ -1147publicstaticfinal String PROP_SHORT = "P"; -1148/** -1149 * The CLI argument name for setting the location of an additional properties file. -1150 */ -1151publicstaticfinal String PROP = "propertyfile"; -1152/** -1153 * The CLI argument name for setting the location of the data directory. +1145 * The long CLI argument name specifying the name of the project to be +1146 * scanned. +1147 */ +1148publicstaticfinal String PROJECT = "project"; +1149/** +1150 * The long CLI argument name specifying the name of the application to +1151 * be scanned. +1152 * +1153 * @deprecated project should be used instead1154 */ -1155publicstaticfinal String DATA_DIRECTORY = "data"; -1156/** -1157 * The CLI argument name for setting the URL for the CVE Data Files. -1158 */ -1159publicstaticfinal String CVE_MOD_12 = "cveUrl12Modified"; -1160/** -1161 * The CLI argument name for setting the URL for the CVE Data Files. +1155 @Deprecated +1156publicstaticfinal String APP_NAME = "app"; +1157/** +1158 * The short CLI argument name specifying the name of the application to +1159 * be scanned. +1160 * +1161 * @deprecated project should be used instead1162 */ -1163publicstaticfinal String CVE_MOD_20 = "cveUrl20Modified"; -1164/** -1165 * The CLI argument name for setting the URL for the CVE Data Files. -1166 */ -1167publicstaticfinal String CVE_BASE_12 = "cveUrl12Base"; -1168/** -1169 * The CLI argument name for setting the URL for the CVE Data Files. -1170 */ -1171publicstaticfinal String CVE_BASE_20 = "cveUrl20Base"; -1172/** -1173 * The short CLI argument name for setting the location of the data directory. -1174 */ -1175publicstaticfinal String DATA_DIRECTORY_SHORT = "d"; -1176/** -1177 * The CLI argument name for setting the location of the data directory. -1178 */ -1179publicstaticfinal String VERBOSE_LOG = "log"; -1180/** -1181 * The short CLI argument name for setting the location of the data directory. -1182 */ -1183publicstaticfinal String VERBOSE_LOG_SHORT = "l"; -1184 +1163 @Deprecated +1164publicstaticfinal String APP_NAME_SHORT = "a"; +1165/** +1166 * The long CLI argument name asking for help. +1167 */ +1168publicstaticfinal String HELP = "help"; +1169/** +1170 * The long CLI argument name asking for advanced help. +1171 */ +1172publicstaticfinal String ADVANCED_HELP = "advancedHelp"; +1173/** +1174 * The short CLI argument name asking for help. +1175 */ +1176publicstaticfinal String HELP_SHORT = "h"; +1177/** +1178 * The long CLI argument name asking for the version. +1179 */ +1180publicstaticfinal String VERSION_SHORT = "v"; +1181/** +1182 * The short CLI argument name asking for the version. +1183 */ +1184publicstaticfinal String VERSION = "version"; 1185/** -1186 * The CLI argument name for setting the depth of symbolic links that will be followed. +1186 * The CLI argument name indicating the proxy port.1187 */ -1188publicstaticfinal String SYM_LINK_DEPTH = "symLink"; +1188publicstaticfinal String PROXY_PORT = "proxyport"; 1189/** -1190 * The CLI argument name for setting the location of the suppression file. +1190 * The CLI argument name indicating the proxy server.1191 */ -1192publicstaticfinal String SUPPRESSION_FILE = "suppression"; +1192publicstaticfinal String PROXY_SERVER = "proxyserver"; 1193/** -1194 * The CLI argument name for setting the location of the suppression file. -1195 */ -1196publicstaticfinal String CVE_VALID_FOR_HOURS = "cveValidForHours"; -1197/** -1198 * Disables the Jar Analyzer. -1199 */ -1200publicstaticfinal String DISABLE_JAR = "disableJar"; -1201/** -1202 * Disables the Archive Analyzer. -1203 */ -1204publicstaticfinal String DISABLE_ARCHIVE = "disableArchive"; -1205/** -1206 * Disables the Python Distribution Analyzer. -1207 */ -1208publicstaticfinal String DISABLE_PY_DIST = "disablePyDist"; -1209/** -1210 * Disables the Python Package Analyzer. -1211 */ -1212publicstaticfinal String DISABLE_PY_PKG = "disablePyPkg"; -1213/** -1214 * Disables the Python Package Analyzer. -1215 */ -1216publicstaticfinal String DISABLE_COMPOSER = "disableComposer"; -1217/** -1218 * Disables the Ruby Gemspec Analyzer. +1194 * The CLI argument name indicating the proxy url. +1195 * +1196 * @deprecated use {@link #PROXY_SERVER} instead +1197 */ +1198 @Deprecated +1199publicstaticfinal String PROXY_URL = "proxyurl"; +1200/** +1201 * The CLI argument name indicating the proxy username. +1202 */ +1203publicstaticfinal String PROXY_USERNAME = "proxyuser"; +1204/** +1205 * The CLI argument name indicating the proxy password. +1206 */ +1207publicstaticfinal String PROXY_PASSWORD = "proxypass"; +1208/** +1209 * The short CLI argument name indicating the connection timeout. +1210 */ +1211publicstaticfinal String CONNECTION_TIMEOUT_SHORT = "c"; +1212/** +1213 * The CLI argument name indicating the connection timeout. +1214 */ +1215publicstaticfinal String CONNECTION_TIMEOUT = "connectiontimeout"; +1216/** +1217 * The short CLI argument name for setting the location of an additional +1218 * properties file.1219 */ -1220publicstaticfinal String DISABLE_RUBYGEMS = "disableRubygems"; +1220publicstaticfinal String PROP_SHORT = "P"; 1221/** -1222 * Disables the Autoconf Analyzer. -1223 */ -1224publicstaticfinal String DISABLE_AUTOCONF = "disableAutoconf"; -1225/** -1226 * Disables the Cmake Analyzer. -1227 */ -1228publicstaticfinal String DISABLE_CMAKE = "disableCmake"; -1229/** -1230 * Disables the Assembly Analyzer. -1231 */ -1232publicstaticfinal String DISABLE_ASSEMBLY = "disableAssembly"; -1233/** -1234 * Disables the Ruby Bundler Audit Analyzer. -1235 */ -1236publicstaticfinal String DISABLE_BUNDLE_AUDIT = "disableBundleAudit"; -1237/** -1238 * Disables the Nuspec Analyzer. -1239 */ -1240publicstaticfinal String DISABLE_NUSPEC = "disableNuspec"; -1241/** -1242 * Disables the Central Analyzer. -1243 */ -1244publicstaticfinal String DISABLE_CENTRAL = "disableCentral"; -1245/** -1246 * Disables the Nexus Analyzer. -1247 */ -1248publicstaticfinal String DISABLE_NEXUS = "disableNexus"; -1249/** -1250 * Disables the OpenSSL Analyzer. -1251 */ -1252publicstaticfinal String DISABLE_OPENSSL = "disableOpenSSL"; -1253/** -1254 * Disables the Node.js Package Analyzer. -1255 */ -1256publicstaticfinal String DISABLE_NODE_JS = "disableNodeJS"; -1257/** -1258 * The URL of the nexus server. -1259 */ -1260publicstaticfinal String NEXUS_URL = "nexus"; +1222 * The CLI argument name for setting the location of an additional +1223 * properties file. +1224 */ +1225publicstaticfinal String PROP = "propertyfile"; +1226/** +1227 * The CLI argument name for setting the location of the data directory. +1228 */ +1229publicstaticfinal String DATA_DIRECTORY = "data"; +1230/** +1231 * The CLI argument name for setting the URL for the CVE Data Files. +1232 */ +1233publicstaticfinal String CVE_MOD_12 = "cveUrl12Modified"; +1234/** +1235 * The CLI argument name for setting the URL for the CVE Data Files. +1236 */ +1237publicstaticfinal String CVE_MOD_20 = "cveUrl20Modified"; +1238/** +1239 * The CLI argument name for setting the URL for the CVE Data Files. +1240 */ +1241publicstaticfinal String CVE_BASE_12 = "cveUrl12Base"; +1242/** +1243 * The CLI argument name for setting the URL for the CVE Data Files. +1244 */ +1245publicstaticfinal String CVE_BASE_20 = "cveUrl20Base"; +1246/** +1247 * The short CLI argument name for setting the location of the data +1248 * directory. +1249 */ +1250publicstaticfinal String DATA_DIRECTORY_SHORT = "d"; +1251/** +1252 * The CLI argument name for setting the location of the data directory. +1253 */ +1254publicstaticfinal String VERBOSE_LOG = "log"; +1255/** +1256 * The short CLI argument name for setting the location of the data +1257 * directory. +1258 */ +1259publicstaticfinal String VERBOSE_LOG_SHORT = "l"; +12601261/** -1262 * Whether or not the defined proxy should be used when connecting to Nexus. -1263 */ -1264publicstaticfinal String NEXUS_USES_PROXY = "nexusUsesProxy"; -1265/** -1266 * The CLI argument name for setting the connection string. -1267 */ -1268publicstaticfinal String CONNECTION_STRING = "connectionString"; -1269/** -1270 * The CLI argument name for setting the database user name. -1271 */ -1272publicstaticfinal String DB_NAME = "dbUser"; -1273/** -1274 * The CLI argument name for setting the database password. -1275 */ -1276publicstaticfinal String DB_PASSWORD = "dbPassword"; -1277/** -1278 * The CLI argument name for setting the database driver name. -1279 */ -1280publicstaticfinal String DB_DRIVER = "dbDriverName"; -1281/** -1282 * The CLI argument name for setting the path to the database driver; in case it is not on the class path. -1283 */ -1284publicstaticfinal String DB_DRIVER_PATH = "dbDriverPath"; -1285/** -1286 * The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems. -1287 */ -1288publicstaticfinal String PATH_TO_MONO = "mono"; -1289/** -1290 * The CLI argument name for setting extra extensions. -1291 */ -1292publicstaticfinal String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions"; -1293/** -1294 * Exclude path argument. -1295 */ -1296publicstaticfinal String EXCLUDE = "exclude"; -1297/** -1298 * The CLI argument name for setting the path to bundle-audit for Ruby bundle analysis. -1299 */ -1300publicstaticfinal String PATH_TO_BUNDLE_AUDIT = "bundleAudit"; -1301 } -1302 } +1262 * The CLI argument name for setting the depth of symbolic links that +1263 * will be followed. +1264 */ +1265publicstaticfinal String SYM_LINK_DEPTH = "symLink"; +1266/** +1267 * The CLI argument name for setting the location of the suppression +1268 * file. +1269 */ +1270publicstaticfinal String SUPPRESSION_FILE = "suppression"; +1271/** +1272 * The CLI argument name for setting the location of the suppression +1273 * file. +1274 */ +1275publicstaticfinal String CVE_VALID_FOR_HOURS = "cveValidForHours"; +1276/** +1277 * Disables the Jar Analyzer. +1278 */ +1279publicstaticfinal String DISABLE_JAR = "disableJar"; +1280/** +1281 * Disables the Archive Analyzer. +1282 */ +1283publicstaticfinal String DISABLE_ARCHIVE = "disableArchive"; +1284/** +1285 * Disables the Python Distribution Analyzer. +1286 */ +1287publicstaticfinal String DISABLE_PY_DIST = "disablePyDist"; +1288/** +1289 * Disables the Python Package Analyzer. +1290 */ +1291publicstaticfinal String DISABLE_PY_PKG = "disablePyPkg"; +1292/** +1293 * Disables the Python Package Analyzer. +1294 */ +1295publicstaticfinal String DISABLE_COMPOSER = "disableComposer"; +1296/** +1297 * Disables the Ruby Gemspec Analyzer. +1298 */ +1299publicstaticfinal String DISABLE_RUBYGEMS = "disableRubygems"; +1300/** +1301 * Disables the Autoconf Analyzer. +1302 */ +1303publicstaticfinal String DISABLE_AUTOCONF = "disableAutoconf"; +1304/** +1305 * Disables the Cmake Analyzer. +1306 */ +1307publicstaticfinal String DISABLE_CMAKE = "disableCmake"; +1308/** +1309 * Disables the Assembly Analyzer. +1310 */ +1311publicstaticfinal String DISABLE_ASSEMBLY = "disableAssembly"; +1312/** +1313 * Disables the Ruby Bundler Audit Analyzer. +1314 */ +1315publicstaticfinal String DISABLE_BUNDLE_AUDIT = "disableBundleAudit"; +1316/** +1317 * Disables the Nuspec Analyzer. +1318 */ +1319publicstaticfinal String DISABLE_NUSPEC = "disableNuspec"; +1320/** +1321 * Disables the Central Analyzer. +1322 */ +1323publicstaticfinal String DISABLE_CENTRAL = "disableCentral"; +1324/** +1325 * Disables the Nexus Analyzer. +1326 */ +1327publicstaticfinal String DISABLE_NEXUS = "disableNexus"; +1328/** +1329 * Disables the OpenSSL Analyzer. +1330 */ +1331publicstaticfinal String DISABLE_OPENSSL = "disableOpenSSL"; +1332/** +1333 * Disables the Node.js Package Analyzer. +1334 */ +1335publicstaticfinal String DISABLE_NODE_JS = "disableNodeJS"; +1336/** +1337 * The URL of the nexus server. +1338 */ +1339publicstaticfinal String NEXUS_URL = "nexus"; +1340/** +1341 * Whether or not the defined proxy should be used when connecting to +1342 * Nexus. +1343 */ +1344publicstaticfinal String NEXUS_USES_PROXY = "nexusUsesProxy"; +1345/** +1346 * The CLI argument name for setting the connection string. +1347 */ +1348publicstaticfinal String CONNECTION_STRING = "connectionString"; +1349/** +1350 * The CLI argument name for setting the database user name. +1351 */ +1352publicstaticfinal String DB_NAME = "dbUser"; +1353/** +1354 * The CLI argument name for setting the database password. +1355 */ +1356publicstaticfinal String DB_PASSWORD = "dbPassword"; +1357/** +1358 * The CLI argument name for setting the database driver name. +1359 */ +1360publicstaticfinal String DB_DRIVER = "dbDriverName"; +1361/** +1362 * The CLI argument name for setting the path to the database driver; in +1363 * case it is not on the class path. +1364 */ +1365publicstaticfinal String DB_DRIVER_PATH = "dbDriverPath"; +1366/** +1367 * The CLI argument name for setting the path to mono for .NET Assembly +1368 * analysis on non-windows systems. +1369 */ +1370publicstaticfinal String PATH_TO_MONO = "mono"; +1371/** +1372 * The CLI argument name for setting extra extensions. +1373 */ +1374publicstaticfinal String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions"; +1375/** +1376 * Exclude path argument. +1377 */ +1378publicstaticfinal String EXCLUDE = "exclude"; +1379/** +1380 * The CLI argument name for setting the path to bundle-audit for Ruby +1381 * bundle analysis. +1382 */ +1383publicstaticfinal String PATH_TO_BUNDLE_AUDIT = "bundleAudit"; +1384/** +1385 * The CLI argument to enable the experimental analyzers. +1386 */ +1387privatestaticfinal String EXPERIMENTAL = "enableExperimental"; +1388 } +1389 }
      diff --git a/dependency-check-cli/xref/org/owasp/dependencycheck/package-frame.html b/dependency-check-cli/xref/org/owasp/dependencycheck/package-frame.html index ee8b4f15b..8d0a7cf67 100644 --- a/dependency-check-cli/xref/org/owasp/dependencycheck/package-frame.html +++ b/dependency-check-cli/xref/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-cli/xref/org/owasp/dependencycheck/package-summary.html b/dependency-check-cli/xref/org/owasp/dependencycheck/package-summary.html index 4e5d566b4..2ee075147 100644 --- a/dependency-check-cli/xref/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-cli/xref/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-cli/xref/overview-frame.html b/dependency-check-cli/xref/overview-frame.html index 8875adeb3..6b5043647 100644 --- a/dependency-check-cli/xref/overview-frame.html +++ b/dependency-check-cli/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.3.6 Reference + Dependency-Check Command Line 1.4.0 Reference diff --git a/dependency-check-cli/xref/overview-summary.html b/dependency-check-cli/xref/overview-summary.html index b129042bf..c3857e7bb 100644 --- a/dependency-check-cli/xref/overview-summary.html +++ b/dependency-check-cli/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.3.6 Reference + Dependency-Check Command Line 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Command Line 1.3.6 Reference

      +

      Dependency-Check Command Line 1.4.0 Reference

      diff --git a/dependency-check-core/apidocs/allclasses-frame.html b/dependency-check-core/apidocs/allclasses-frame.html index 60836e66a..05755dd79 100644 --- a/dependency-check-core/apidocs/allclasses-frame.html +++ b/dependency-check-core/apidocs/allclasses-frame.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Core 1.3.6 API) - +All Classes (Dependency-Check Core 1.4.0 API) + @@ -66,6 +66,7 @@
    6. EscapeTool
    7. Evidence
    8. EvidenceCollection
    9. +
    10. Experimental
    11. ExtractionUtil
    12. FalsePositiveAnalyzer
    13. FieldAnalyzer
    14. @@ -114,6 +115,7 @@
    15. ReportGenerator
    16. ReportGenerator.Format
    17. RubyBundleAuditAnalyzer
    18. +
    19. RubyBundlerAnalyzer
    20. RubyGemspecAnalyzer
    21. ScanAgentException
    22. SearchFieldAnalyzer
    23. diff --git a/dependency-check-core/apidocs/allclasses-noframe.html b/dependency-check-core/apidocs/allclasses-noframe.html index bbb58a347..b19fee50c 100644 --- a/dependency-check-core/apidocs/allclasses-noframe.html +++ b/dependency-check-core/apidocs/allclasses-noframe.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Core 1.3.6 API) - +All Classes (Dependency-Check Core 1.4.0 API) + @@ -66,6 +66,7 @@
    24. EscapeTool
    25. Evidence
    26. EvidenceCollection
    27. +
    28. Experimental
    29. ExtractionUtil
    30. FalsePositiveAnalyzer
    31. FieldAnalyzer
    32. @@ -114,6 +115,7 @@
    33. ReportGenerator
    34. ReportGenerator.Format
    35. RubyBundleAuditAnalyzer
    36. +
    37. RubyBundlerAnalyzer
    38. RubyGemspecAnalyzer
    39. ScanAgentException
    40. SearchFieldAnalyzer
    41. diff --git a/dependency-check-core/apidocs/constant-values.html b/dependency-check-core/apidocs/constant-values.html index 7f7cb2348..769130ba9 100644 --- a/dependency-check-core/apidocs/constant-values.html +++ b/dependency-check-core/apidocs/constant-values.html @@ -2,10 +2,10 @@ - + -Constant Field Values (Dependency-Check Core 1.3.6 API) - +Constant Field Values (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-summary.html index 56d10156b..e7f15ede6 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.agent (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.agent (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.analyzer
      +

      Annotation Type Experimental

      +
      +
      +
      + +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.html index 67053885f..fafcb3bab 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.html @@ -2,10 +2,10 @@ - + -FalsePositiveAnalyzer (Dependency-Check Core 1.3.6 API) - +FalsePositiveAnalyzer (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.analyzer
      +

      Class RubyBundlerAnalyzer

      +
      +
      + +
      +
        +
      • +
        +
        All Implemented Interfaces:
        +
        FileFilter, Analyzer, FileTypeAnalyzer
        +
        +
        +
        +
        public class RubyBundlerAnalyzer
        +extends RubyGemspecAnalyzer
        +
        This analyzer accepts the fully resolved .gemspec created by the Ruby bundler + (http://bundler.io) for better evidence results. It also tries to resolve the + dependency packagePath to where the gem is actually installed. Then during AnalysisPhase.PRE_FINDING_ANALYSIS + DependencyBundlingAnalyzer will merge two .gemspec dependencies + together if Dependency.getPackagePath() are the same. + + Ruby bundler creates new .gemspec files under a folder called + "specifications" at deploy time, in addition to the original .gemspec files + from source. The bundler generated .gemspec files always contain fully + resolved attributes thus provide more accurate evidences, whereas the + original .gemspec from source often contain variables for attributes that + can't be used for evidences. + + Note this analyzer share the same + Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED as + RubyGemspecAnalyzer, so it will enabled/disabled with + RubyGemspecAnalyzer.
        +
        +
        Author:
        +
        Bianca Jiang (biancajiang@gmail.com)
        +
        +
      • +
      +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Summary

          +
      + + + + + + + +
      Constructors 
      Constructor and Description
      RubyBundlerAnalyzer() 
      + + + + + + + +
      + +
      + + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html index 5fdad9e43..1a40d02dc 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html @@ -2,10 +2,10 @@ - + -RubyGemspecAnalyzer (Dependency-Check Core 1.3.6 API) - +RubyGemspecAnalyzer (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.analyzer.Experimental

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FalsePositiveAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FalsePositiveAnalyzer.html index 165a520eb..34280ee2a 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FalsePositiveAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FalsePositiveAnalyzer.html @@ -2,10 +2,10 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer (Dependency-Check Core 1.3.6 API) - +Uses of Class org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer

      +
      +
      No usage of org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/RubyGemspecAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/RubyGemspecAnalyzer.html index 716aabc53..2a77327a2 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/RubyGemspecAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/RubyGemspecAnalyzer.html @@ -2,10 +2,10 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer (Dependency-Check Core 1.3.6 API) - +Uses of Class org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-summary.html index 3ed3ed848..e172a63bf 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -45,6 +45,7 @@
    42. PythonDistributionAnalyzer
    43. PythonPackageAnalyzer
    44. RubyBundleAuditAnalyzer
    45. +
    46. RubyBundlerAnalyzer
    47. RubyGemspecAnalyzer
    48. VulnerabilitySuppressionAnalyzer
    49. @@ -52,6 +53,10 @@ +

      Annotation Types

      + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-summary.html index 7ce3c5580..e0ab00959 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-summary.html index 05435c8cc..d1e4b5caa 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.central (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.central (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/composer/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/composer/package-summary.html index 0a0ec49f7..e754ceed8 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/composer/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.composer (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.composer (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-summary.html index 9b8a29a5d..40ffd1f1c 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-summary.html index ae80ba694..e0e083652 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-summary.html index e4ea1bb5e..14cac647f 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-summary.html index 0f20b36e3..1854d8a78 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-summary.html index 577fdb89e..0ad06a42a 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,13 +13,13 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-summary.html index 3ac9ba898..245317dfa 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-summary.html index 6021f5bcf..2d76f5c19 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.update.cpe (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.update.cpe (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/exception/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/exception/package-summary.html index bbc801aab..1ae11af6d 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/exception/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/exception/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.update.exception (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.update.exception (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html index e2ab9207d..a3d290d99 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.update.nvd (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.update.nvd (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-summary.html index ed7b50e29..3934485fe 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.update (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.data.update (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,13 +13,13 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,13 +13,13 @@ @@ -13,13 +13,13 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/dependency/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/dependency/package-summary.html index f2f657e2d..1c0ed11f0 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/dependency/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/dependency/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.dependency (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.dependency (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/package-summary.html index 41bc14bb0..fdf138c82 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.exception (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.exception (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/package-summary.html index d9616e417..19f8da6c5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/reporting/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/reporting/package-summary.html index 5d96b4108..0a209d862 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/reporting/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/reporting/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.reporting (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.reporting (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/suppression/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/suppression/package-summary.html index 63d63a43c..256d713a5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/suppression/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/suppression/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.suppression (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.suppression (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/utils/package-summary.html index 0bdddc820..0e688a987 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/utils/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.utils (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.utils (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,13 +13,13 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-summary.html index 158f105c4..94f6bd963 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.3.6 API) - +org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/overview-summary.html b/dependency-check-core/apidocs/overview-summary.html index ab2979fa8..5a7547168 100644 --- a/dependency-check-core/apidocs/overview-summary.html +++ b/dependency-check-core/apidocs/overview-summary.html @@ -2,10 +2,10 @@ - + -Overview (Dependency-Check Core 1.3.6 API) - +Overview (Dependency-Check Core 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.exception.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.exception.html index a2058e0d6..110ccb0a2 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.exception.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.exception.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.html index 50b289dbf..2865e11e1 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.analyzer33
      61%
      1591/2594
      43%
      605/1396
      4.307
      org.owasp.dependencycheck.analyzer37
      60%
      1650/2711
      44%
      656/1472
      4.393
      org.owasp.dependencycheck.analyzer.exception2
      25%
      4/16
      N/A
      1
      @@ -33,23 +33,23 @@ packageTable.sort(0); AbstractFileTypeAnalyzer
      84%
      33/39
      80%
      8/10
      1.429 - AbstractSuppressionAnalyzer
      80%
      48/60
      71%
      10/14
      3.833 + AbstractSuppressionAnalyzer
      75%
      48/64
      71%
      10/14
      4 AnalysisPhase
      100%
      11/11
      N/A
      0 Analyzer
      N/A
      N/A
      1 - AnalyzerService
      100%
      4/4
      N/A
      1 + AnalyzerService
      89%
      17/19
      100%
      6/6
      3 - ArchiveAnalyzer
      36%
      73/200
      24%
      22/90
      5.188 + ArchiveAnalyzer
      36%
      73/200
      25%
      23/90
      5.188 AssemblyAnalyzer
      65%
      75/115
      55%
      21/38
      6 - AutoconfAnalyzer
      90%
      67/74
      76%
      26/34
      3.111 + AutoconfAnalyzer
      90%
      64/71
      76%
      26/34
      3.222 CMakeAnalyzer
      91%
      65/71
      80%
      8/10
      2.143 - CPEAnalyzer
      81%
      189/233
      73%
      98/134
      4.607 + CPEAnalyzer
      83%
      194/232
      76%
      103/134
      4.607 CPEAnalyzer$IdentifierConfidence
      100%
      4/4
      N/A
      4.607 CPEAnalyzer$IdentifierMatch
      38%
      15/39
      16%
      4/24
      4.607 @@ -59,18 +59,20 @@ packageTable.sort(0); CpeSuppressionAnalyzer
      90%
      9/10
      66%
      4/6
      2.333 - DependencyBundlingAnalyzer
      43%
      68/156
      31%
      51/160
      7.5 + DependencyBundlingAnalyzer
      40%
      72/178
      30%
      57/184
      7.688 + + Experimental
      N/A
      N/A
      0 FalsePositiveAnalyzer
      47%
      106/224
      25%
      58/230
      10.385 - FileNameAnalyzer
      77%
      17/22
      40%
      4/10
      2.667 + FileNameAnalyzer
      89%
      17/19
      62%
      5/8
      2.333 FileTypeAnalyzer
      N/A
      N/A
      1 HintAnalyzer
      74%
      37/50
      56%
      17/30
      6 - JarAnalyzer
      65%
      339/520
      51%
      176/342
      7.29 - JarAnalyzer$ClassNameInformation
      80%
      17/21
      80%
      8/10
      7.29 + JarAnalyzer
      66%
      349/522
      56%
      195/346
      7.355 + JarAnalyzer$ClassNameInformation
      80%
      17/21
      80%
      8/10
      7.355 NexusAnalyzer
      20%
      14/70
      4%
      1/24
      3.375 @@ -80,15 +82,19 @@ packageTable.sort(0); NvdCveAnalyzer
      68%
      24/35
      50%
      6/12
      2.125 - OpenSSLAnalyzer
      91%
      34/37
      71%
      10/14
      2.125 + OpenSSLAnalyzer
      91%
      32/35
      71%
      10/14
      2.25 PythonDistributionAnalyzer
      85%
      89/104
      65%
      30/46
      3.308 - PythonPackageAnalyzer
      91%
      67/73
      75%
      15/20
      2.091 + PythonPackageAnalyzer
      91%
      66/72
      77%
      14/18
      2 - RubyBundleAuditAnalyzer
      16%
      28/169
      4%
      3/68
      4.615 + RubyBundleAuditAnalyzer
      16%
      32/200
      2%
      2/74
      5.154 - RubyGemspecAnalyzer
      93%
      42/45
      60%
      6/10
      1.875 + RubyBundlerAnalyzer
      66%
      20/30
      43%
      13/30
      4.5 + RubyBundlerAnalyzer$1
      100%
      2/2
      N/A
      4.5 + + RubyGemspecAnalyzer
      76%
      49/64
      40%
      8/20
      2.3 + RubyGemspecAnalyzer$1
      0%
      0/2
      N/A
      2.3 VulnerabilitySuppressionAnalyzer
      90%
      9/10
      66%
      4/6
      2.333 @@ -99,6 +105,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.central.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.central.html index ac63d3121..117831c2b 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.central.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.central.html @@ -37,6 +37,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.composer.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.composer.html index 80e26a770..115ee547f 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.composer.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.composer.html @@ -41,6 +41,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cpe.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cpe.html index df48f61ad..4edeba148 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cpe.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cpe.html @@ -43,6 +43,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cwe.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cwe.html index 74337087f..587dc687a 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cwe.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cwe.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.lucene.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.lucene.html index c0f552ab6..bde8a78fe 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.lucene.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.lucene.html @@ -51,6 +51,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nexus.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nexus.html index 15bfa8625..2145cb668 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nexus.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nexus.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nuget.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nuget.html index e229851ce..f613aec14 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nuget.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nuget.html @@ -43,6 +43,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nvdcve.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nvdcve.html index fedf78698..244356600 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nvdcve.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nvdcve.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.data.nvdcve9
      42%
      312/733
      45%
      93/206
      4.065
      org.owasp.dependencycheck.data.nvdcve9
      41%
      313/749
      43%
      93/216
      4.177
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html index d4f4cf8f0..2b6834b47 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/66
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/65
      0%
      0/18
      1.5
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.exception.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.exception.html index 6300f5421..21ddc6106 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.exception.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.exception.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.html index 5de83f310..32a856cb0 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.html @@ -17,9 +17,9 @@ Package # Classes Line Coverage Branch Coverage Complexity org.owasp.dependencycheck.data.update6
      14%
      52/348
      11%
      14/122
      5.6 - org.owasp.dependencycheck.data.update.cpe3
      0%
      0/66
      0%
      0/18
      1.5 + org.owasp.dependencycheck.data.update.cpe3
      0%
      0/65
      0%
      0/18
      1.5 org.owasp.dependencycheck.data.update.exception2
      0%
      0/12
      N/A
      1 - org.owasp.dependencycheck.data.update.nvd8
      67%
      281/415
      67%
      129/192
      2.865 + org.owasp.dependencycheck.data.update.nvd8
      69%
      288/413
      69%
      134/194
      2.865 - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html index 63ff4a057..50f2c262d 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.data.update.nvd8
      67%
      281/415
      67%
      129/192
      2.865
      org.owasp.dependencycheck.data.update.nvd8
      69%
      288/413
      69%
      134/194
      2.865
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.dependency.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.dependency.html index f4355cb9e..03f1974b5 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.dependency.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.dependency.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.dependency14
      65%
      403/616
      53%
      153/286
      1.989
      org.owasp.dependencycheck.dependency14
      64%
      412/637
      55%
      162/294
      1.989
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.exception.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.exception.html index 56e84b5b7..dd0a5f410 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.exception.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.exception.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html index 223e4633d..51b4bcd0f 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html @@ -16,9 +16,9 @@ - + - + @@ -27,17 +27,17 @@ - + - + - - + + - - - + + +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck1
      54%
      102/187
      57%
      37/64
      3.174
      org.owasp.dependencycheck1
      58%
      108/186
      60%
      39/64
      3.174
      org.owasp.dependencycheck.agent1
      0%
      0/226
      0%
      0/36
      1.319
      org.owasp.dependencycheck.analyzer33
      61%
      1591/2594
      43%
      605/1396
      4.307
      org.owasp.dependencycheck.analyzer37
      60%
      1650/2711
      44%
      656/1472
      4.393
      org.owasp.dependencycheck.analyzer.exception2
      25%
      4/16
      N/A
      1
      org.owasp.dependencycheck.data.central1
      83%
      51/61
      83%
      20/24
      10
      org.owasp.dependencycheck.data.composer3
      79%
      53/67
      45%
      19/42
      3.417
      org.owasp.dependencycheck.data.lucene8
      78%
      97/124
      53%
      35/66
      3.32
      org.owasp.dependencycheck.data.nexus2
      20%
      22/105
      10%
      3/30
      2.444
      org.owasp.dependencycheck.data.nuget4
      66%
      44/66
      15%
      6/40
      2.238
      org.owasp.dependencycheck.data.nvdcve9
      42%
      312/733
      45%
      93/206
      4.065
      org.owasp.dependencycheck.data.nvdcve9
      41%
      313/749
      43%
      93/216
      4.177
      org.owasp.dependencycheck.data.update6
      14%
      52/348
      11%
      14/122
      5.6
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/66
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/65
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update.exception2
      0%
      0/12
      N/A
      1
      org.owasp.dependencycheck.data.update.nvd8
      67%
      281/415
      67%
      129/192
      2.865
      org.owasp.dependencycheck.dependency14
      65%
      403/616
      53%
      153/286
      1.989
      org.owasp.dependencycheck.data.update.nvd8
      69%
      288/413
      69%
      134/194
      2.865
      org.owasp.dependencycheck.dependency14
      64%
      412/637
      55%
      162/294
      1.989
      org.owasp.dependencycheck.exception2
      0%
      0/16
      N/A
      1
      org.owasp.dependencycheck.reporting4
      0%
      0/158
      0%
      0/88
      5.067
      org.owasp.dependencycheck.suppression6
      71%
      218/303
      62%
      112/178
      3.018
      org.owasp.dependencycheck.utils11
      63%
      232/365
      60%
      113/186
      3.759
      org.owasp.dependencycheck.xml.pom7
      60%
      128/212
      52%
      36/68
      2.319
      org.owasp.dependencycheck.suppression6
      74%
      255/343
      64%
      118/182
      3.286
      org.owasp.dependencycheck.utils11
      63%
      231/364
      60%
      113/186
      3.759
      org.owasp.dependencycheck.xml.pom7
      61%
      133/217
      54%
      38/70
      2.286
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.reporting.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.reporting.html index 1364a1fc5..7e16d0ad5 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.reporting.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.reporting.html @@ -42,6 +42,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.suppression.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.suppression.html index 1c800f27b..fbef3fa49 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.suppression.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.suppression.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.suppression6
      71%
      218/303
      62%
      112/178
      3.018
      org.owasp.dependencycheck.suppression6
      74%
      255/343
      64%
      118/182
      3.286
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.utils.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.utils.html index 042ed1071..52101da76 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.utils.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.utils.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.utils11
      63%
      232/365
      60%
      113/186
      3.759
      org.owasp.dependencycheck.utils11
      63%
      231/364
      60%
      113/186
      3.759
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.pom.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.pom.html index 4694475ab..82f1de399 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.pom.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.pom.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.xml.pom7
      60%
      128/212
      52%
      36/68
      2.319
      org.owasp.dependencycheck.xml.pom7
      61%
      133/217
      54%
      38/70
      2.286
      - + diff --git a/dependency-check-core/cobertura/frame-summary.html b/dependency-check-core/cobertura/frame-summary.html index addb221a0..deda9ca60 100644 --- a/dependency-check-core/cobertura/frame-summary.html +++ b/dependency-check-core/cobertura/frame-summary.html @@ -16,10 +16,10 @@ - - + + - + @@ -28,17 +28,17 @@ - + - + - - + + - - - + + +
      Package # Classes Line Coverage Branch Coverage Complexity
      All Packages133
      53%
      3705/6868
      45%
      1400/3106
      3.106
      org.owasp.dependencycheck1
      54%
      102/187
      57%
      37/64
      3.174
      All Packages137
      54%
      3828/7062
      45%
      1475/3208
      3.151
      org.owasp.dependencycheck1
      58%
      108/186
      60%
      39/64
      3.174
      org.owasp.dependencycheck.agent1
      0%
      0/226
      0%
      0/36
      1.319
      org.owasp.dependencycheck.analyzer33
      61%
      1591/2594
      43%
      605/1396
      4.307
      org.owasp.dependencycheck.analyzer37
      60%
      1650/2711
      44%
      656/1472
      4.393
      org.owasp.dependencycheck.analyzer.exception2
      25%
      4/16
      N/A
      1
      org.owasp.dependencycheck.data.central1
      83%
      51/61
      83%
      20/24
      10
      org.owasp.dependencycheck.data.composer3
      79%
      53/67
      45%
      19/42
      3.417
      org.owasp.dependencycheck.data.lucene8
      78%
      97/124
      53%
      35/66
      3.32
      org.owasp.dependencycheck.data.nexus2
      20%
      22/105
      10%
      3/30
      2.444
      org.owasp.dependencycheck.data.nuget4
      66%
      44/66
      15%
      6/40
      2.238
      org.owasp.dependencycheck.data.nvdcve9
      42%
      312/733
      45%
      93/206
      4.065
      org.owasp.dependencycheck.data.nvdcve9
      41%
      313/749
      43%
      93/216
      4.177
      org.owasp.dependencycheck.data.update6
      14%
      52/348
      11%
      14/122
      5.6
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/66
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/65
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update.exception2
      0%
      0/12
      N/A
      1
      org.owasp.dependencycheck.data.update.nvd8
      67%
      281/415
      67%
      129/192
      2.865
      org.owasp.dependencycheck.dependency14
      65%
      403/616
      53%
      153/286
      1.989
      org.owasp.dependencycheck.data.update.nvd8
      69%
      288/413
      69%
      134/194
      2.865
      org.owasp.dependencycheck.dependency14
      64%
      412/637
      55%
      162/294
      1.989
      org.owasp.dependencycheck.exception2
      0%
      0/16
      N/A
      1
      org.owasp.dependencycheck.reporting4
      0%
      0/158
      0%
      0/88
      5.067
      org.owasp.dependencycheck.suppression6
      71%
      218/303
      62%
      112/178
      3.018
      org.owasp.dependencycheck.utils11
      63%
      232/365
      60%
      113/186
      3.759
      org.owasp.dependencycheck.xml.pom7
      60%
      128/212
      52%
      36/68
      2.319
      org.owasp.dependencycheck.suppression6
      74%
      255/343
      64%
      118/182
      3.286
      org.owasp.dependencycheck.utils11
      63%
      231/364
      60%
      113/186
      3.759
      org.owasp.dependencycheck.xml.pom7
      61%
      133/217
      54%
      38/70
      2.286
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html index 59c67ca46..c49aa0f85 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      Engine
      54%
      102/187
      57%
      37/64
      3.174
      Engine
      58%
      108/186
      60%
      39/64
      3.174
       
      @@ -135,14 +135,14 @@
            * The list of dependencies.
       59  
            */
      -  60  3
           private List<Dependency> dependencies = new ArrayList<Dependency>();
      +  60  8
           private List<Dependency> dependencies = new ArrayList<Dependency>();
       61  
           /**
       62  
            * A Map of analyzers grouped by Analysis phase.
       63  
            */
      -  64  3
           private Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
      +  64  8
           private Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
       65  
       
       66   @@ -151,7 +151,7 @@
            * A Map of analyzers grouped by Analysis phase.
       68  
            */
      -  69  3
           private Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>();
      +  69  8
           private Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>();
       70  
       
       71   @@ -160,14 +160,14 @@
            * The ClassLoader to use when dynamically loading Analyzer and Update services.
       73  
            */
      -  74  3
           private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader();
      +  74  8
           private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader();
       75  
           /**
       76  
            * The Logger for use throughout the class.
       77  
            */
      -  78  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class);
      +  78  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class);
       79  
       
       80   @@ -180,9 +180,9 @@
            * @throws DatabaseException thrown if there is an error connecting to the database
       84  
            */
      -  85  3
           public Engine() throws DatabaseException {
      -  86  3
               initializeEngine();
      -  87  3
           }
      +  85  8
           public Engine() throws DatabaseException {
      +  86  8
               initializeEngine();
      +  87  8
           }
       88  
       
       89   @@ -215,9 +215,9 @@
            */
       105  
           protected final void initializeEngine() throws DatabaseException {
      -  106  3
               ConnectionFactory.initialize();
      -  107  3
               loadAnalyzers();
      -  108  3
           }
      +  106  8
               ConnectionFactory.initialize();
      +  107  8
               loadAnalyzers();
      +  108  8
           }
       109  
       
       110   @@ -240,608 +240,607 @@
            */
       120  
           private void loadAnalyzers() {
      -  121  3
               if (!analyzers.isEmpty()) {
      +  121  8
               if (!analyzers.isEmpty()) {
       122  0
                   return;
       123  
               }
      -  124  33
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      -  125  30
                   analyzers.put(phase, new ArrayList<Analyzer>());
      +  124  88
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      +  125  80
                   analyzers.put(phase, new ArrayList<Analyzer>());
       126  
               }
       127  
       
      -  128  3
               final AnalyzerService service = new AnalyzerService(serviceClassLoader);
      -  129  3
               final Iterator<Analyzer> iterator = service.getAnalyzers();
      -  130  72
               while (iterator.hasNext()) {
      -  131  69
                   final Analyzer a = iterator.next();
      -  132  69
                   analyzers.get(a.getAnalysisPhase()).add(a);
      -  133  69
                   if (a instanceof FileTypeAnalyzer) {
      -  134  45
                       this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
      -  135   +  128  8
               final AnalyzerService service = new AnalyzerService(serviceClassLoader);
      +  129  8
               final List<Analyzer> iterator = service.getAnalyzers();
      +  130  8
               for (Analyzer a : iterator) {
      +  131  192
                   analyzers.get(a.getAnalysisPhase()).add(a);
      +  132  192
                   if (a instanceof FileTypeAnalyzer) {
      +  133  128
                       this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
      +  134  
                   }
      -  136  69
               }
      -  137  3
           }
      +  135  192
               }
      +  136  8
           }
      +  137   +
       
       138   -
       
      +
           /**
       139   -
           /**
      -  140  
            * Get the List of the analyzers for a specific phase of analysis.
      +  140   +
            *
       141   -
            *
      -  142  
            * @param phase the phase to get the configured analyzers.
      -  143   +  142  
            * @return the analyzers loaded
      +  143   +
            */
       144   -
            */
      -  145  
           public List<Analyzer> getAnalyzers(AnalysisPhase phase) {
      -  146  0
               return analyzers.get(phase);
      +  145  0
               return analyzers.get(phase);
      +  146   +
           }
       147   -
           }
      +
       
       148   -
       
      +
           /**
       149   -
           /**
      -  150  
            * Get the dependencies identified.
      +  150   +
            *
       151   -
            *
      -  152  
            * @return the dependencies identified
      +  152   +
            */
       153   -
            */
      -  154  
           public List<Dependency> getDependencies() {
      -  155  45
               return dependencies;
      +  154  98
               return dependencies;
      +  155   +
           }
       156   -
           }
      +
       
       157   -
       
      +
           /**
       158   -
           /**
      -  159  
            * Sets the dependencies.
      +  159   +
            *
       160   -
            *
      -  161  
            * @param dependencies the dependencies
      +  161   +
            */
       162   -
            */
      -  163  
           public void setDependencies(List<Dependency> dependencies) {
      -  164  0
               this.dependencies = dependencies;
      -  165  0
           }
      +  163  0
               this.dependencies = dependencies;
      +  164  0
           }
      +  165   +
       
       166   -
       
      +
           /**
       167   -
           /**
      +
            * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
       168   -
            * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
      +
            * identified are added to the dependency collection.
       169   -
            * identified are added to the dependency collection.
      +
            *
       170   -
            *
      -  171  
            * @param paths an array of paths to files or directories to be analyzed
      +  171   +
            * @return the list of dependencies scanned
       172   -
            * @return the list of dependencies scanned
      +
            * @since v0.3.2.5
       173   -
            * @since v0.3.2.5
      +
            */
       174   -
            */
      -  175  
           public List<Dependency> scan(String[] paths) {
      -  176  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      -  177  0
               for (String path : paths) {
      -  178  0
                   final List<Dependency> d = scan(path);
      -  179  0
                   if (d != null) {
      -  180  0
                       deps.addAll(d);
      +  175  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      +  176  0
               for (String path : paths) {
      +  177  0
                   final List<Dependency> d = scan(path);
      +  178  0
                   if (d != null) {
      +  179  0
                       deps.addAll(d);
      +  180   +
                   }
       181   -
                   }
      -  182  
               }
      -  183  0
               return deps;
      +  182  0
               return deps;
      +  183   +
           }
       184   -
           }
      +
       
       185   -
       
      +
           /**
       186   -
           /**
      +
            * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified
       187   -
            * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified
      +
            * are added to the dependency collection.
       188   -
            * are added to the dependency collection.
      +
            *
       189   -
            *
      -  190  
            * @param path the path to a file or directory to be analyzed
      +  190   +
            * @return the list of dependencies scanned
       191   -
            * @return the list of dependencies scanned
      +
            */
       192   -
            */
      -  193  
           public List<Dependency> scan(String path) {
      -  194  0
               final File file = new File(path);
      -  195  0
               return scan(file);
      +  193  0
               final File file = new File(path);
      +  194  0
               return scan(file);
      +  195   +
           }
       196   -
           }
      +
       
       197   -
       
      +
           /**
       198   -
           /**
      -  199  
            * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
      +  199   +
            * identified are added to the dependency collection.
       200   -
            * identified are added to the dependency collection.
      +
            *
       201   -
            *
      -  202  
            * @param files an array of paths to files or directories to be analyzed.
      -  203   +  202  
            * @return the list of dependencies
      +  203   +
            * @since v0.3.2.5
       204   -
            * @since v0.3.2.5
      +
            */
       205   -
            */
      -  206  
           public List<Dependency> scan(File[] files) {
      -  207  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      -  208  0
               for (File file : files) {
      -  209  0
                   final List<Dependency> d = scan(file);
      -  210  0
                   if (d != null) {
      -  211  0
                       deps.addAll(d);
      +  206  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      +  207  0
               for (File file : files) {
      +  208  0
                   final List<Dependency> d = scan(file);
      +  209  0
                   if (d != null) {
      +  210  0
                       deps.addAll(d);
      +  211   +
                   }
       212   -
                   }
      -  213  
               }
      -  214  0
               return deps;
      +  213  0
               return deps;
      +  214   +
           }
       215   -
           }
      +
       
       216   -
       
      +
           /**
       217   -
           /**
      -  218  
            * Scans a collection of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
      -  219   +  218  
            * identified are added to the dependency collection.
      +  219   +
            *
       220   -
            *
      -  221  
            * @param files a set of paths to files or directories to be analyzed
      +  221   +
            * @return the list of dependencies scanned
       222   -
            * @return the list of dependencies scanned
      -  223  
            * @since v0.3.2.5
      +  223   +
            */
       224   -
            */
      -  225  
           public List<Dependency> scan(Collection<File> files) {
      -  226  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      -  227  0
               for (File file : files) {
      -  228  0
                   final List<Dependency> d = scan(file);
      -  229  0
                   if (d != null) {
      -  230  0
                       deps.addAll(d);
      -  231   +  225  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      +  226  0
               for (File file : files) {
      +  227  0
                   final List<Dependency> d = scan(file);
      +  228  0
                   if (d != null) {
      +  229  0
                       deps.addAll(d);
      +  230  
                   }
      -  232  0
               }
      -  233  0
               return deps;
      +  231  0
               }
      +  232  0
               return deps;
      +  233   +
           }
       234   -
           }
      +
       
       235   -
       
      +
           /**
       236   -
           /**
      -  237  
            * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified
      -  238   +  237  
            * are added to the dependency collection.
      +  238   +
            *
       239   -
            *
      -  240  
            * @param file the path to a file or directory to be analyzed
      -  241   +  240  
            * @return the list of dependencies scanned
      -  242   +  241  
            * @since v0.3.2.4
      +  242   +
            */
       243   -
            */
      -  244  
           public List<Dependency> scan(File file) {
      -  245  4
               if (file.exists()) {
      -  246  4
                   if (file.isDirectory()) {
      -  247  2
                       return scanDirectory(file);
      -  248   +  244  10
               if (file.exists()) {
      +  245  10
                   if (file.isDirectory()) {
      +  246  6
                       return scanDirectory(file);
      +  247  
                   } else {
      -  249  2
                       final Dependency d = scanFile(file);
      -  250  2
                       if (d != null) {
      -  251  2
                           final List<Dependency> deps = new ArrayList<Dependency>();
      -  252  2
                           deps.add(d);
      -  253  2
                           return deps;
      +  248  4
                       final Dependency d = scanFile(file);
      +  249  4
                       if (d != null) {
      +  250  4
                           final List<Dependency> deps = new ArrayList<Dependency>();
      +  251  4
                           deps.add(d);
      +  252  4
                           return deps;
      +  253   +
                       }
       254   -
                       }
      +
                   }
       255   -
                   }
      -  256  
               }
      -  257  0
               return null;
      +  256  0
               return null;
      +  257   +
           }
       258   -
           }
      +
       
       259   -
       
      +
           /**
       260   -
           /**
      -  261  
            * Recursively scans files and directories. Any dependencies identified are added to the dependency collection.
      +  261   +
            *
       262   -
            *
      -  263  
            * @param dir the directory to scan
      -  264   +  263  
            * @return the list of Dependency objects scanned
      +  264   +
            */
       265   -
            */
      -  266  
           protected List<Dependency> scanDirectory(File dir) {
      -  267  38
               final File[] files = dir.listFiles();
      -  268  38
               final List<Dependency> deps = new ArrayList<Dependency>();
      -  269  38
               if (files != null) {
      -  270  74
                   for (File f : files) {
      -  271  36
                       if (f.isDirectory()) {
      -  272  36
                           final List<Dependency> d = scanDirectory(f);
      -  273  36
                           if (d != null) {
      -  274  36
                               deps.addAll(d);
      -  275   +  266  92
               final File[] files = dir.listFiles();
      +  267  92
               final List<Dependency> deps = new ArrayList<Dependency>();
      +  268  92
               if (files != null) {
      +  269  186
                   for (File f : files) {
      +  270  94
                       if (f.isDirectory()) {
      +  271  86
                           final List<Dependency> d = scanDirectory(f);
      +  272  86
                           if (d != null) {
      +  273  86
                               deps.addAll(d);
      +  274  
                           }
      -  276  36
                       } else {
      -  277  0
                           final Dependency d = scanFile(f);
      -  278  0
                           deps.add(d);
      -  279   +  275  86
                       } else {
      +  276  8
                           final Dependency d = scanFile(f);
      +  277  8
                           deps.add(d);
      +  278  
                       }
      +  279   +
                   }
       280   -
                   }
      -  281  
               }
      -  282  38
               return deps;
      +  281  92
               return deps;
      +  282   +
           }
       283   -
           }
      +
       
       284   -
       
      +
           /**
       285   -
           /**
      -  286  
            * Scans a specified file. If a dependency is identified it is added to the dependency collection.
      +  286   +
            *
       287   -
            *
      -  288  
            * @param file The file to scan
      -  289   +  288  
            * @return the scanned dependency
      +  289   +
            */
       290   -
            */
      -  291  
           protected Dependency scanFile(File file) {
      -  292  2
               Dependency dependency = null;
      -  293  2
               if (file.isFile()) {
      -  294  2
                   if (accept(file)) {
      -  295  2
                       dependency = new Dependency(file);
      -  296  2
                       dependencies.add(dependency);
      +  291  12
               Dependency dependency = null;
      +  292  12
               if (file.isFile()) {
      +  293  12
                   if (accept(file)) {
      +  294  8
                       dependency = new Dependency(file);
      +  295  8
                       dependencies.add(dependency);
      +  296   +
                   }
       297   -
                   }
      -  298  
               } else {
      -  299  0
                   LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file);
      -  300   +  298  0
                   LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file);
      +  299  
               }
      -  301  2
               return dependency;
      +  300  12
               return dependency;
      +  301   +
           }
       302   -
           }
      +
       
       303   -
       
      +
           /**
       304   -
           /**
      -  305  
            * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via
      -  306   +  305  
            * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for
      -  307   +  306  
            * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the
      -  308   +  307  
            * dependencies list.
      +  308   +
            */
       309   -
            */
      -  310  
           public void analyzeDependencies() {
      -  311  1
               boolean autoUpdate = true;
      -  312   +  310  4
               boolean autoUpdate = true;
      +  311  
               try {
      -  313  1
                   autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
      -  314  0
               } catch (InvalidSettingException ex) {
      -  315  0
                   LOGGER.debug("Invalid setting for auto-update; using true.");
      -  316  1
               }
      -  317  1
               if (autoUpdate) {
      -  318  0
                   doUpdates();
      +  312  4
                   autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
      +  313  0
               } catch (InvalidSettingException ex) {
      +  314  0
                   LOGGER.debug("Invalid setting for auto-update; using true.");
      +  315  4
               }
      +  316  4
               if (autoUpdate) {
      +  317  0
                   doUpdates();
      +  318   +
               }
       319   -
               }
      +
       
       320   -
       
      -  321  
               //need to ensure that data exists
      -  322   +  321  
               try {
      -  323  1
                   ensureDataExists();
      -  324  0
               } catch (NoDataException ex) {
      -  325  0
                   LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
      -  326  0
                   LOGGER.debug("", ex);
      -  327  0
                   return;
      -  328  0
               } catch (DatabaseException ex) {
      -  329  0
                   LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
      -  330  0
                   LOGGER.debug("", ex);
      -  331  0
                   return;
      -  332   +  322  4
                   ensureDataExists();
      +  323  0
               } catch (NoDataException ex) {
      +  324  0
                   LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
      +  325  0
                   LOGGER.debug("", ex);
      +  326  0
                   return;
      +  327  0
               } catch (DatabaseException ex) {
      +  328  0
                   LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
      +  329  0
                   LOGGER.debug("", ex);
      +  330  0
                   return;
      +  331  
       
      -  333  1
               }
      -  334   +  332  4
               }
      +  333   +
       
      +  334  4
               LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------");
      +  335  4
               LOGGER.info("Analysis Starting");
      +  336  4
               final long analysisStart = System.currentTimeMillis();
      +  337  
       
      -  335  1
               LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------");
      -  336  1
               LOGGER.info("Analysis Starting");
      -  337  1
               final long analysisStart = System.currentTimeMillis();
       338   -
       
      -  339  
               // analysis phases
      -  340  11
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      -  341  10
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      -  342   +  339  44
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      +  340  40
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      +  341   +
       
      +  342  40
                   for (Analyzer a : analyzerList) {
      +  343  96
                       a = initializeAnalyzer(a);
      +  344  
       
      -  343  10
                   for (Analyzer a : analyzerList) {
      -  344  23
                       a = initializeAnalyzer(a);
       345   -
       
      -  346  
                       /* need to create a copy of the collection because some of the
      -  347   +  346  
                        * analyzers may modify it. This prevents ConcurrentModificationExceptions.
      -  348   +  347  
                        * This is okay for adds/deletes because it happens per analyzer.
      -  349   +  348  
                        */
      -  350  23
                       LOGGER.debug("Begin Analyzer '{}'", a.getName());
      -  351  23
                       final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies);
      -  352  23
                       for (Dependency d : dependencySet) {
      -  353  46
                           boolean shouldAnalyze = true;
      -  354  46
                           if (a instanceof FileTypeAnalyzer) {
      -  355  30
                               final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a;
      -  356  30
                               shouldAnalyze = fAnalyzer.accept(d.getActualFile());
      -  357   +  349  96
                       LOGGER.debug("Begin Analyzer '{}'", a.getName());
      +  350  96
                       final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies);
      +  351  96
                       for (Dependency d : dependencySet) {
      +  352  192
                           boolean shouldAnalyze = true;
      +  353  192
                           if (a instanceof FileTypeAnalyzer) {
      +  354  128
                               final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a;
      +  355  128
                               shouldAnalyze = fAnalyzer.accept(d.getActualFile());
      +  356  
                           }
      -  358  46
                           if (shouldAnalyze) {
      -  359  20
                               LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath());
      -  360   +  357  192
                           if (shouldAnalyze) {
      +  358  76
                               LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath());
      +  359  
                               try {
      -  361  20
                                   a.analyze(d, this);
      -  362  0
                               } catch (AnalysisException ex) {
      -  363  0
                                   LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath());
      -  364  0
                                   LOGGER.debug("", ex);
      -  365  0
                               } catch (Throwable ex) {
      -  366   +  360  76
                                   a.analyze(d, this);
      +  361  0
                               } catch (AnalysisException ex) {
      +  362  0
                                   LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath());
      +  363  0
                                   LOGGER.debug("", ex);
      +  364  0
                               } catch (Throwable ex) {
      +  365  
                                   //final AnalysisException ax = new AnalysisException(axMsg, ex);
      -  367  0
                                   LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath());
      -  368  0
                                   LOGGER.debug("", ex);
      -  369  20
                               }
      -  370   +  366  0
                                   LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath());
      +  367  0
                                   LOGGER.debug("", ex);
      +  368  76
                               }
      +  369  
                           }
      -  371  46
                       }
      -  372  23
                   }
      -  373   +  370  192
                       }
      +  371  96
                   }
      +  372  
               }
      -  374  11
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      -  375  10
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      -  376   +  373  44
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      +  374  40
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      +  375  
       
      -  377  10
                   for (Analyzer a : analyzerList) {
      -  378  23
                       closeAnalyzer(a);
      -  379  23
                   }
      +  376  40
                   for (Analyzer a : analyzerList) {
      +  377  96
                       closeAnalyzer(a);
      +  378  96
                   }
      +  379   +
               }
       380   -
               }
      -  381  
       
      -  382  1
               LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------");
      -  383  1
               LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart);
      -  384  1
           }
      +  381  4
               LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------");
      +  382  4
               LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart);
      +  383  4
           }
      +  384   +
       
       385   -
       
      +
           /**
       386   -
           /**
      -  387  
            * Initializes the given analyzer.
      +  387   +
            *
       388   -
            *
      -  389  
            * @param analyzer the analyzer to initialize
      -  390   +  389  
            * @return the initialized analyzer
      +  390   +
            */
       391   -
            */
      -  392  
           protected Analyzer initializeAnalyzer(Analyzer analyzer) {
      -  393   +  392  
               try {
      -  394  23
                   LOGGER.debug("Initializing {}", analyzer.getName());
      -  395  23
                   analyzer.initialize();
      -  396  0
               } catch (Throwable ex) {
      -  397  0
                   LOGGER.error("Exception occurred initializing {}.", analyzer.getName());
      -  398  0
                   LOGGER.debug("", ex);
      -  399   +  393  96
                   LOGGER.debug("Initializing {}", analyzer.getName());
      +  394  96
                   analyzer.initialize();
      +  395  2
               } catch (Throwable ex) {
      +  396  2
                   LOGGER.error("Exception occurred initializing {}.", analyzer.getName());
      +  397  2
                   LOGGER.debug("", ex);
      +  398  
                   try {
      -  400  0
                       analyzer.close();
      -  401  0
                   } catch (Throwable ex1) {
      -  402  0
                       LOGGER.trace("", ex1);
      -  403  0
                   }
      -  404  23
               }
      -  405  23
               return analyzer;
      +  399  2
                       analyzer.close();
      +  400  0
                   } catch (Throwable ex1) {
      +  401  0
                       LOGGER.trace("", ex1);
      +  402  2
                   }
      +  403  94
               }
      +  404  96
               return analyzer;
      +  405   +
           }
       406   -
           }
      +
       
       407   -
       
      +
           /**
       408   -
           /**
      -  409  
            * Closes the given analyzer.
      +  409   +
            *
       410   -
            *
      -  411  
            * @param analyzer the analyzer to close
      +  411   +
            */
       412   -
            */
      -  413  
           protected void closeAnalyzer(Analyzer analyzer) {
      -  414  23
               LOGGER.debug("Closing Analyzer '{}'", analyzer.getName());
      -  415   +  413  96
               LOGGER.debug("Closing Analyzer '{}'", analyzer.getName());
      +  414  
               try {
      -  416  23
                   analyzer.close();
      -  417  0
               } catch (Throwable ex) {
      -  418  0
                   LOGGER.trace("", ex);
      -  419  23
               }
      -  420  23
           }
      +  415  96
                   analyzer.close();
      +  416  0
               } catch (Throwable ex) {
      +  417  0
                   LOGGER.trace("", ex);
      +  418  96
               }
      +  419  96
           }
      +  420   +
       
       421   -
       
      +
           /**
       422   -
           /**
      -  423  
            * Cycles through the cached web data sources and calls update on all of them.
      +  423   +
            */
       424   -
            */
      -  425  
           public void doUpdates() {
      -  426  0
               LOGGER.info("Checking for updates");
      -  427  0
               final long updateStart = System.currentTimeMillis();
      -  428  0
               final UpdateService service = new UpdateService(serviceClassLoader);
      -  429  0
               final Iterator<CachedWebDataSource> iterator = service.getDataSources();
      -  430  0
               while (iterator.hasNext()) {
      -  431  0
                   final CachedWebDataSource source = iterator.next();
      -  432   +  425  0
               LOGGER.info("Checking for updates");
      +  426  0
               final long updateStart = System.currentTimeMillis();
      +  427  0
               final UpdateService service = new UpdateService(serviceClassLoader);
      +  428  0
               final Iterator<CachedWebDataSource> iterator = service.getDataSources();
      +  429  0
               while (iterator.hasNext()) {
      +  430  0
                   final CachedWebDataSource source = iterator.next();
      +  431  
                   try {
      -  433  0
                       source.update();
      -  434  0
                   } catch (UpdateException ex) {
      -  435  0
                       LOGGER.warn(
      -  436   +  432  0
                       source.update();
      +  433  0
                   } catch (UpdateException ex) {
      +  434  0
                       LOGGER.warn(
      +  435  
                               "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities.");
      -  437  0
                       LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex);
      -  438  0
                   }
      -  439  0
               }
      -  440  0
               LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart);
      -  441  0
           }
      +  436  0
                       LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex);
      +  437  0
                   }
      +  438  0
               }
      +  439  0
               LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart);
      +  440  0
           }
      +  441   +
       
       442   -
       
      +
           /**
       443   -
           /**
      -  444  
            * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used.
      +  444   +
            *
       445   -
            *
      -  446  
            * @return a list of Analyzers
      +  446   +
            */
       447   -
            */
      -  448  
           public List<Analyzer> getAnalyzers() {
      -  449  0
               final List<Analyzer> ret = new ArrayList<Analyzer>();
      -  450  0
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      -  451  0
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      -  452  0
                   ret.addAll(analyzerList);
      -  453   +  448  0
               final List<Analyzer> ret = new ArrayList<Analyzer>();
      +  449  0
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      +  450  0
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      +  451  0
                   ret.addAll(analyzerList);
      +  452  
               }
      -  454  0
               return ret;
      +  453  0
               return ret;
      +  454   +
           }
       455   -
           }
      +
       
       456   -
       
      +
           /**
       457   -
           /**
      -  458  
            * Checks all analyzers to see if an extension is supported.
      +  458   +
            *
       459   -
            *
      -  460  
            * @param file a file extension
      -  461   +  460  
            * @return true or false depending on whether or not the file extension is supported
      +  461   +
            */
       462   -
            */
      -  463  
           @Override
      -  464   +  463  
           public boolean accept(File file) {
      -  465  851
               if (file == null) {
      -  466  0
                   return false;
      -  467   +  464  1710
               if (file == null) {
      +  465  0
                   return false;
      +  466  
               }
      -  468  851
               boolean scan = false;
      -  469  851
               for (FileTypeAnalyzer a : this.fileTypeAnalyzers) {
      -  470   +  467  1710
               boolean scan = false;
      +  468  1710
               for (FileTypeAnalyzer a : this.fileTypeAnalyzers) {
      +  469  
                   /* note, we can't break early on this loop as the analyzers need to know if
      -  471   +  470  
                    they have files to work on prior to initialization */
      -  472  12765
                   scan |= a.accept(file);
      -  473  12765
               }
      -  474  851
               return scan;
      +  471  27360
                   scan |= a.accept(file);
      +  472  27360
               }
      +  473  1710
               return scan;
      +  474   +
           }
       475   -
           }
      +
       
       476   -
       
      +
           /**
       477   -
           /**
      -  478  
            * Returns the set of file type analyzers.
      +  478   +
            *
       479   -
            *
      -  480  
            * @return the set of file type analyzers
      +  480   +
            */
       481   -
            */
      -  482  
           public Set<FileTypeAnalyzer> getFileTypeAnalyzers() {
      -  483  0
               return this.fileTypeAnalyzers;
      -  484   +  482  0
               return this.fileTypeAnalyzers;
      +  483  
           }
      -  485   +  484  
       
      -  486   +  485  
           /**
      -  487   +  486  
            * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown.
      -  488   +  487  
            *
      -  489   +  488  
            * @throws NoDataException thrown if no data exists in the CPE Index
      -  490   +  489  
            * @throws DatabaseException thrown if there is an exception opening the database
      -  491   +  490  
            */
      -  492   +  491  
           private void ensureDataExists() throws NoDataException, DatabaseException {
      -  493  1
               final CveDB cve = new CveDB();
      -  494   +  492  4
               final CveDB cve = new CveDB();
      +  493  
               try {
      -  495  1
                   cve.open();
      -  496  1
                   if (!cve.dataExists()) {
      -  497  0
                       throw new NoDataException("No documents exist");
      -  498   +  494  4
                   cve.open();
      +  495  4
                   if (!cve.dataExists()) {
      +  496  0
                       throw new NoDataException("No documents exist");
      +  497  
                   }
      -  499  0
               } catch (DatabaseException ex) {
      -  500  0
                   throw new NoDataException(ex.getMessage(), ex);
      -  501   +  498  0
               } catch (DatabaseException ex) {
      +  499  0
                   throw new NoDataException(ex.getMessage(), ex);
      +  500  
               } finally {
      -  502  1
                   cve.close();
      -  503  1
               }
      -  504  1
           }
      -  505   +  501  4
                   cve.close();
      +  502  4
               }
      +  503  4
           }
      +  504  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html index e6e44c6a0..39ca02839 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html @@ -1847,6 +1847,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractAnalyzer.html index 885fb0a2c..4e270fef6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractAnalyzer.html @@ -63,7 +63,7 @@
        * @author Jeremy Long
       23  
        */
      -  24  154
       public abstract class AbstractAnalyzer implements Analyzer {
      +  24  414
       public abstract class AbstractAnalyzer implements Analyzer {
       25  
       
       26   @@ -82,7 +82,7 @@
           public void initialize() throws Exception {
       33  
               //do nothing
      -  34  10
           }
      +  34  32
           }
       35  
       
       36   @@ -101,11 +101,11 @@
           public void close() throws Exception {
       43  
               //do nothing
      -  44  55
           }
      +  44  162
           }
       45  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html index 1e7a0e834..6412d37b1 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html @@ -105,9 +105,9 @@
            * Base constructor that all children must call. This checks the configuration to determine if the analyzer is enabled.
       44  
            */
      -  45  111
           public AbstractFileTypeAnalyzer() {
      -  46  111
               reset();
      -  47  111
           }
      +  45  304
           public AbstractFileTypeAnalyzer() {
      +  46  304
               reset();
      +  47  304
           }
       48  
       //</editor-fold>
       49   @@ -120,14 +120,14 @@
            * The logger.
       53  
            */
      -  54  1
           private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class);
      +  54  2
           private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class);
       55  
           /**
       56  
            * Whether the file type analyzer detected any files it needs to analyze.
       57  
            */
      -  58  111
           private boolean filesMatched = false;
      +  58  304
           private boolean filesMatched = false;
       59  
       
       60   @@ -159,8 +159,8 @@
            */
       74  
           protected void setFilesMatched(boolean filesMatched) {
      -  75  39
               this.filesMatched = filesMatched;
      -  76  39
           }
      +  75  88
               this.filesMatched = filesMatched;
      +  76  88
           }
       77  
       
       78   @@ -169,7 +169,7 @@
            * A flag indicating whether or not the analyzer is enabled.
       80  
            */
      -  81  111
           private boolean enabled = true;
      +  81  304
           private boolean enabled = true;
       82  
       
       83   @@ -184,7 +184,7 @@
            */
       88  
           public boolean isEnabled() {
      -  89  1
               return enabled;
      +  89  2
               return enabled;
       90  
           }
       91   @@ -201,8 +201,8 @@
            */
       97  
           public void setEnabled(boolean enabled) {
      -  98  6
               this.enabled = enabled;
      -  99  6
           }
      +  98  16
               this.enabled = enabled;
      +  99  16
           }
       100  
       //</editor-fold>
       101   @@ -301,14 +301,14 @@
           @Override
       148  
           public final void initialize() throws Exception {
      -  149  61
               if (filesMatched) {
      -  150  44
                   initializeFileTypeAnalyzer();
      +  149  164
               if (filesMatched) {
      +  150  102
                   initializeFileTypeAnalyzer();
       151  
               } else {
      -  152  17
                   enabled = false;
      +  152  62
                   enabled = false;
       153  
               }
      -  154  59
           }
      +  154  156
           }
       155  
       
       156   @@ -321,16 +321,16 @@
           @Override
       160  
           public final void reset() {
      -  161  111
               final String key = getAnalyzerEnabledSettingKey();
      +  161  304
               final String key = getAnalyzerEnabledSettingKey();
       162  
               try {
      -  163  111
                   enabled = Settings.getBoolean(key, true);
      +  163  304
                   enabled = Settings.getBoolean(key, true);
       164  0
               } catch (InvalidSettingException ex) {
       165  0
                   LOGGER.warn("Invalid setting for property '{}'", key);
       166  0
                   LOGGER.debug("", ex);
       167  0
                   LOGGER.warn("{} has been disabled", getName());
      -  168  111
               }
      -  169  111
           }
      +  168  304
               }
      +  169  304
           }
       170  
       
       171   @@ -353,30 +353,30 @@
           @Override
       180  
           public final void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      -  181  28
               if (enabled) {
      -  182  28
                   analyzeFileType(dependency, engine);
      +  181  64
               if (enabled) {
      +  182  64
                   analyzeFileType(dependency, engine);
       183  
               }
      -  184  27
           }
      +  184  62
           }
       185  
       
       186  
           @Override
       187  
           public boolean accept(File pathname) {
      -  188  12821
               final FileFilter filter = getFileFilter();
      -  189  12821
               boolean accepted = false;
      -  190  12821
               if (null == filter) {
      +  188  27542
               final FileFilter filter = getFileFilter();
      +  189  27542
               boolean accepted = false;
      +  190  27542
               if (null == filter) {
       191  0
                   LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName());
      -  192  12821
               } else if (enabled) {
      -  193  11093
                   accepted = filter.accept(pathname);
      -  194  11093
                   if (accepted) {
      -  195  33
                       filesMatched = true;
      +  192  27542
               } else if (enabled) {
      +  193  24010
                   accepted = filter.accept(pathname);
      +  194  24010
                   if (accepted) {
      +  195  78
                       filesMatched = true;
       196  
                   }
       197  
               }
      -  198  12821
               return accepted;
      +  198  27542
               return accepted;
       199  
           }
       200   @@ -409,9 +409,9 @@
            */
       214  
           protected static Set<String> newHashSet(String... strings) {
      -  215  5
               final Set<String> set = new HashSet<String>(strings.length);
      -  216  5
               Collections.addAll(set, strings);
      -  217  5
               return set;
      +  215  10
               final Set<String> set = new HashSet<String>(strings.length);
      +  216  10
               Collections.addAll(set, strings);
      +  217  10
               return set;
       218  
           }
       219   @@ -422,6 +422,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer.html index a89907dcd..0a4b1628b 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      AbstractSuppressionAnalyzer
      80%
      48/60
      71%
      10/14
      3.833
      AbstractSuppressionAnalyzer
      75%
      48/64
      71%
      10/14
      4
       
      @@ -90,229 +90,239 @@  36  
       import org.slf4j.LoggerFactory;
       37   -
       
      +
       import org.xml.sax.SAXException;
       38   -
       /**
      +
       
       39   -
        * Abstract base suppression analyzer that contains methods for parsing the suppression xml file.
      +
       /**
       40   -
        *
      +
        * Abstract base suppression analyzer that contains methods for parsing the
       41   -
        * @author Jeremy Long
      +
        * suppression xml file.
       42   -
        */
      -  43  12
       public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
      +
        *
      +  43   +
        * @author Jeremy Long
       44   -
       
      -  45   -
           /**
      +
        */
      +  45  32
       public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
       46   -
            * The Logger for use throughout the class
      +
       
       47   -
            */
      -  48  1
           private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class);
      +
           /**
      +  48   +
            * The Logger for use throughout the class
       49   -
       
      -  50   -
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
      +
            */
      +  50  2
           private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class);
       51   -
           /**
      +
       
       52   -
            * Returns a list of file EXTENSIONS supported by this analyzer.
      +
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
       53   -
            *
      +
           /**
       54   -
            * @return a list of file EXTENSIONS supported by this analyzer.
      +
            * Returns a list of file EXTENSIONS supported by this analyzer.
       55   -
            */
      +
            *
       56   -
           public Set<String> getSupportedExtensions() {
      -  57  1
               return null;
      +
            * @return a list of file EXTENSIONS supported by this analyzer.
      +  57   +
            */
       58   -
           }
      -  59   -
       
      +
           public Set<String> getSupportedExtensions() {
      +  59  2
               return null;
       60   -
           //</editor-fold>
      +
           }
       61   -
           /**
      +
       
       62   -
            * The initialize method loads the suppression XML file.
      +
           //</editor-fold>
       63   -
            *
      +
           /**
       64   -
            * @throws Exception thrown if there is an exception
      +
            * The initialize method loads the suppression XML file.
       65   -
            */
      +
            *
       66   -
           @Override
      +
            * @throws Exception thrown if there is an exception
       67   +
            */
      +  68   +
           @Override
      +  69  
           public void initialize() throws Exception {
      -  68  5
               super.initialize();
      -  69  5
               loadSuppressionData();
      -  70  4
           }
      -  71   -
       
      -  72   -
           /**
      +  70  14
               super.initialize();
      +  71  14
               loadSuppressionData();
      +  72  12
           }
       73   -
            * The list of suppression rules
      +
       
       74   -
            */
      +
           /**
       75   -
           private List<SuppressionRule> rules;
      +
            * The list of suppression rules
       76   -
       
      +
            */
       77   -
           /**
      +
           private List<SuppressionRule> rules;
       78   -
            * Get the value of rules.
      +
       
       79   -
            *
      +
           /**
       80   -
            * @return the value of rules
      +
            * Get the value of rules.
       81   -
            */
      +
            *
       82   -
           public List<SuppressionRule> getRules() {
      -  83  14
               return rules;
      +
            * @return the value of rules
      +  83   +
            */
       84   -
           }
      -  85   -
       
      +
           public List<SuppressionRule> getRules() {
      +  85  52
               return rules;
       86   -
           /**
      -  87   -
            * Set the value of rules.
      -  88   -
            *
      -  89   -
            * @param rules new value of rules
      -  90   -
            */
      -  91   -
           public void setRules(List<SuppressionRule> rules) {
      -  92  0
               this.rules = rules;
      -  93  0
           }
      -  94   -
       
      -  95   -
           /**
      -  96   -
            * Loads the suppression rules file.
      -  97   -
            *
      -  98   -
            * @throws SuppressionParseException thrown if the XML cannot be parsed.
      -  99   -
            */
      -  100   -
           private void loadSuppressionData() throws SuppressionParseException {
      -  101  5
               final SuppressionParser parser = new SuppressionParser();
      -  102  5
               File file = null;
      -  103   -
               try {
      -  104  5
                   rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml"));
      -  105  0
               } catch (SuppressionParseException ex) {
      -  106  0
                   LOGGER.debug("Unable to parse the base suppression data file", ex);
      -  107  5
               }
      -  108  5
               final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
      -  109  5
               if (suppressionFilePath == null) {
      -  110  2
                   return;
      -  111   -
               }
      -  112  3
               boolean deleteTempFile = false;
      -  113   -
               try {
      -  114  3
                   final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
      -  115  3
                   if (uriRx.matcher(suppressionFilePath).matches()) {
      -  116  1
                       deleteTempFile = true;
      -  117  1
                       file = FileUtils.getTempFile("suppression", "xml");
      -  118  1
                       final URL url = new URL(suppressionFilePath);
      -  119   -
                       try {
      -  120  1
                           Downloader.fetchFile(url, file, false);
      -  121  0
                       } catch (DownloadFailedException ex) {
      -  122  0
                           Downloader.fetchFile(url, file, true);
      -  123  1
                       }
      -  124  1
                   } else {
      -  125  2
                       file = new File(suppressionFilePath);
      -  126  2
                       if (!file.exists()) {
      -  127  2
                           final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath);
      -  128  2
                           if (suppressionsFromClasspath != null) {
      -  129  1
                               deleteTempFile = true;
      -  130  1
                               file = FileUtils.getTempFile("suppression", "xml");
      -  131   -
                               try {
      -  132  1
                                   org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file);
      -  133  0
                               } catch (IOException ex) {
      -  134  0
                                   throwSuppressionParseException("Unable to locate suppressions file in classpath", ex);
      -  135  1
                               }
      -  136   -
                           }
      -  137   -
                       }
      -  138   -
                   }
      -  139   -
       
      -  140  3
                   if (file != null) {
      -  141   -
                       try {
      -  142   -
                           //rules = parser.parseSuppressionRules(file);
      -  143  3
                           rules.addAll(parser.parseSuppressionRules(file));
      -  144  2
                           LOGGER.debug("{} suppression rules were loaded.", rules.size());
      -  145  1
                       } catch (SuppressionParseException ex) {
      -  146  1
                           LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath());
      -  147  1
                           LOGGER.warn(ex.getMessage());
      -  148  1
                           LOGGER.debug("", ex);
      -  149  1
                           throw ex;
      -  150  2
                       }
      -  151   -
                   }
      -  152  0
               } catch (DownloadFailedException ex) {
      -  153  0
                   throwSuppressionParseException("Unable to fetch the configured suppression file", ex);
      -  154  0
               } catch (MalformedURLException ex) {
      -  155  0
                   throwSuppressionParseException("Configured suppression file has an invalid URL", ex);
      -  156  1
               } catch (IOException ex) {
      -  157  1
                   throwSuppressionParseException("Unable to create temp file for suppressions", ex);
      -  158   -
               } finally {
      -  159  3
                   if (deleteTempFile && file != null) {
      -  160  2
                       FileUtils.delete(file);
      -  161   -
                   }
      -  162   -
               }
      -  163  2
           }
      -  164   -
       
      -  165   -
           /**
      -  166   -
            * Utility method to throw parse exceptions.
      -  167   -
            *
      -  168   -
            * @param message the exception message
      -  169   -
            * @param exception the cause of the exception
      -  170   -
            * @throws SuppressionParseException throws the generated SuppressionParseException
      -  171   -
            */
      -  172   -
           private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException {
      -  173  1
               LOGGER.warn(message);
      -  174  1
               LOGGER.debug("", exception);
      -  175  1
               throw new SuppressionParseException(message, exception);
      -  176  
           }
      +  87   +
       
      +  88   +
           /**
      +  89   +
            * Set the value of rules.
      +  90   +
            *
      +  91   +
            * @param rules new value of rules
      +  92   +
            */
      +  93   +
           public void setRules(List<SuppressionRule> rules) {
      +  94  0
               this.rules = rules;
      +  95  0
           }
      +  96   +
       
      +  97   +
           /**
      +  98   +
            * Loads the suppression rules file.
      +  99   +
            *
      +  100   +
            * @throws SuppressionParseException thrown if the XML cannot be parsed.
      +  101   +
            */
      +  102   +
           private void loadSuppressionData() throws SuppressionParseException {
      +  103  14
               final SuppressionParser parser = new SuppressionParser();
      +  104  14
               File file = null;
      +  105   +
               try {
      +  106  14
                   rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml"));
      +  107  0
               } catch (SuppressionParseException ex) {
      +  108  0
                   LOGGER.error("Unable to parse the base suppression data file");
      +  109  0
                   LOGGER.debug("Unable to parse the base suppression data file", ex);
      +  110  0
               } catch (SAXException ex) {
      +  111  0
                   LOGGER.error("Unable to parse the base suppression data file");
      +  112  0
                   LOGGER.debug("Unable to parse the base suppression data file", ex);
      +  113  14
               }
      +  114  14
               final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
      +  115  14
               if (suppressionFilePath == null) {
      +  116  8
                   return;
      +  117   +
               }
      +  118  6
               boolean deleteTempFile = false;
      +  119   +
               try {
      +  120  6
                   final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
      +  121  6
                   if (uriRx.matcher(suppressionFilePath).matches()) {
      +  122  2
                       deleteTempFile = true;
      +  123  2
                       file = FileUtils.getTempFile("suppression", "xml");
      +  124  2
                       final URL url = new URL(suppressionFilePath);
      +  125   +
                       try {
      +  126  2
                           Downloader.fetchFile(url, file, false);
      +  127  0
                       } catch (DownloadFailedException ex) {
      +  128  0
                           Downloader.fetchFile(url, file, true);
      +  129  2
                       }
      +  130  2
                   } else {
      +  131  4
                       file = new File(suppressionFilePath);
      +  132  4
                       if (!file.exists()) {
      +  133  4
                           final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath);
      +  134  4
                           if (suppressionsFromClasspath != null) {
      +  135  2
                               deleteTempFile = true;
      +  136  2
                               file = FileUtils.getTempFile("suppression", "xml");
      +  137   +
                               try {
      +  138  2
                                   org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file);
      +  139  0
                               } catch (IOException ex) {
      +  140  0
                                   throwSuppressionParseException("Unable to locate suppressions file in classpath", ex);
      +  141  2
                               }
      +  142   +
                           }
      +  143   +
                       }
      +  144   +
                   }
      +  145   +
       
      +  146  6
                   if (file != null) {
      +  147   +
                       try {
      +  148   +
                           //rules = parser.parseSuppressionRules(file);
      +  149  6
                           rules.addAll(parser.parseSuppressionRules(file));
      +  150  4
                           LOGGER.debug("{} suppression rules were loaded.", rules.size());
      +  151  2
                       } catch (SuppressionParseException ex) {
      +  152  2
                           LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath());
      +  153  2
                           LOGGER.warn(ex.getMessage());
      +  154  2
                           LOGGER.debug("", ex);
      +  155  2
                           throw ex;
      +  156  4
                       }
      +  157   +
                   }
      +  158  0
               } catch (DownloadFailedException ex) {
      +  159  0
                   throwSuppressionParseException("Unable to fetch the configured suppression file", ex);
      +  160  0
               } catch (MalformedURLException ex) {
      +  161  0
                   throwSuppressionParseException("Configured suppression file has an invalid URL", ex);
      +  162  2
               } catch (IOException ex) {
      +  163  2
                   throwSuppressionParseException("Unable to create temp file for suppressions", ex);
      +  164   +
               } finally {
      +  165  6
                   if (deleteTempFile && file != null) {
      +  166  4
                       FileUtils.delete(file);
      +  167   +
                   }
      +  168   +
               }
      +  169  4
           }
      +  170   +
       
      +  171   +
           /**
      +  172   +
            * Utility method to throw parse exceptions.
      +  173   +
            *
      +  174   +
            * @param message the exception message
      +  175   +
            * @param exception the cause of the exception
      +  176   +
            * @throws SuppressionParseException throws the generated
       177   +
            * SuppressionParseException
      +  178   +
            */
      +  179   +
           private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException {
      +  180  2
               LOGGER.warn(message);
      +  181  2
               LOGGER.debug("", exception);
      +  182  2
               throw new SuppressionParseException(message, exception);
      +  183   +
           }
      +  184  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalysisPhase.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalysisPhase.html index 2eb5636fa..031b1eaa4 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalysisPhase.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalysisPhase.html @@ -65,7 +65,7 @@
        * @author Jeremy Long
       24  
        */
      -  25  17
       public enum AnalysisPhase {
      +  25  40
       public enum AnalysisPhase {
       26  
       
       27   @@ -74,74 +74,74 @@
            * Initialization phase.
       29  
            */
      -  30  1
           INITIAL,
      +  30  2
           INITIAL,
       31  
           /**
       32  
            * Pre information collection phase.
       33  
            */
      -  34  1
           PRE_INFORMATION_COLLECTION,
      +  34  2
           PRE_INFORMATION_COLLECTION,
       35  
           /**
       36  
            * Information collection phase.
       37  
            */
      -  38  1
           INFORMATION_COLLECTION,
      +  38  2
           INFORMATION_COLLECTION,
       39  
           /**
       40  
            * Pre identifier analysis phase.
       41  
            */
      -  42  1
           PRE_IDENTIFIER_ANALYSIS,
      +  42  2
           PRE_IDENTIFIER_ANALYSIS,
       43  
           /**
       44  
            * Identifier analysis phase.
       45  
            */
      -  46  1
           IDENTIFIER_ANALYSIS,
      +  46  2
           IDENTIFIER_ANALYSIS,
       47  
           /**
       48  
            * Post identifier analysis phase.
       49  
            */
      -  50  1
           POST_IDENTIFIER_ANALYSIS,
      +  50  2
           POST_IDENTIFIER_ANALYSIS,
       51  
           /**
       52  
            * Pre finding analysis phase.
       53  
            */
      -  54  1
           PRE_FINDING_ANALYSIS,
      +  54  2
           PRE_FINDING_ANALYSIS,
       55  
           /**
       56  
            * Finding analysis phase.
       57  
            */
      -  58  1
           FINDING_ANALYSIS,
      +  58  2
           FINDING_ANALYSIS,
       59  
           /**
       60  
            * Post analysis phase.
       61  
            */
      -  62  1
           POST_FINDING_ANALYSIS,
      +  62  2
           POST_FINDING_ANALYSIS,
       63  
           /**
       64  
            * The final analysis phase.
       65  
            */
      -  66  1
           FINAL
      +  66  2
           FINAL
       67  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Analyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Analyzer.html index 4bed9ac2d..b656e1876 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Analyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Analyzer.html @@ -161,6 +161,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html index 30ef18a47..66b6502b9 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      AnalyzerService
      100%
      4/4
      N/A
      1
      AnalyzerService
      89%
      17/19
      100%
      6/6
      3
       
      @@ -56,71 +56,106 @@  19  
       
       20   -
       import java.util.Iterator;
      +
       import java.util.ArrayList;
       21   -
       import java.util.ServiceLoader;
      +
       import java.util.Iterator;
       22   -
       
      +
       import java.util.List;
       23   -
       /**
      +
       import java.util.ServiceLoader;
       24   -
        * The Analyzer Service Loader. This class loads all services that implement
      +
       import org.owasp.dependencycheck.utils.InvalidSettingException;
       25   -
        * org.owasp.dependencycheck.analyzer.Analyzer.
      +
       import org.owasp.dependencycheck.utils.Settings;
       26   -
        *
      +
       import org.slf4j.LoggerFactory;
       27   -
        * @author Jeremy Long
      +
       
       28   -
        */
      +
       /**
       29   -
       public class AnalyzerService {
      +
        * The Analyzer Service Loader. This class loads all services that implement
       30   -
       
      +
        * org.owasp.dependencycheck.analyzer.Analyzer.
       31   -
           /**
      +
        *
       32   -
            * The service loader for analyzers.
      +
        * @author Jeremy Long
       33   -
            */
      +
        */
       34   -
           private final ServiceLoader<Analyzer> loader;
      +
       public class AnalyzerService {
       35   -
       
      -  36  
           /**
      +  36   +
            * The Logger for use throughout the class.
       37   -
            * Creates a new instance of AnalyzerService.
      -  38   -
            *
      -  39   -
            * @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services
      -  40  
            */
      -  41  4
           public AnalyzerService(ClassLoader classLoader) {
      -  42  4
               loader = ServiceLoader.load(Analyzer.class, classLoader);
      -  43  4
           }
      +  38  2
           private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnalyzerService.class);
      +  39   +
       
      +  40   +
           /**
      +  41   +
            * The service loader for analyzers.
      +  42   +
            */
      +  43   +
           private final ServiceLoader<Analyzer> service;
       44  
       
       45  
           /**
       46   -
            * Returns an Iterator for all instances of the Analyzer interface.
      +
            * Creates a new instance of AnalyzerService.
       47  
            *
       48   -
            * @return an iterator of Analyzers.
      +
            * @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services
       49  
            */
      -  50   -
           public Iterator<Analyzer> getAnalyzers() {
      -  51  4
               return loader.iterator();
      -  52   -
           }
      +  50  12
           public AnalyzerService(ClassLoader classLoader) {
      +  51  12
               service = ServiceLoader.load(Analyzer.class, classLoader);
      +  52  12
           }
       53   +
       
      +  54   +
           /**
      +  55   +
            * Returns a list of all instances of the Analyzer interface.
      +  56   +
            *
      +  57   +
            * @return a list of Analyzers.
      +  58   +
            */
      +  59   +
           public List<Analyzer> getAnalyzers() {
      +  60  14
               final List<Analyzer> analyzers = new ArrayList<Analyzer>();
      +  61  14
               final Iterator<Analyzer> iterator = service.iterator();
      +  62  14
               boolean experimentalEnabled = false;
      +  63   +
               try {
      +  64  14
                   experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false);
      +  65  0
               } catch (InvalidSettingException ex) {
      +  66  0
                   LOGGER.error("invalide experimental setting", ex);
      +  67  14
               }
      +  68  350
               while (iterator.hasNext()) {
      +  69  336
                   final Analyzer a = iterator.next();
      +  70  336
                   if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) {
      +  71  18
                       continue;
      +  72   +
                   }
      +  73  318
                   LOGGER.debug("Loaded Analyzer {}", a.getName());
      +  74  318
                   analyzers.add(a);
      +  75  318
               }
      +  76  14
               return analyzers;
      +  77   +
           }
      +  78  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.html index 5db7b5552..9c5baf4ab 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      ArchiveAnalyzer
      36%
      73/200
      24%
      22/90
      5.188
      ArchiveAnalyzer
      36%
      73/200
      25%
      23/90
      5.188
       
      @@ -147,7 +147,7 @@
        * @author Jeremy Long
       65  
        */
      -  66  4
       public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
      +  66  12
       public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
       67  
       
       68   @@ -156,35 +156,35 @@
            * The logger.
       70  
            */
      -  71  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class);
      +  71  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class);
       72  
           /**
       73  
            * The count of directories created during analysis. This is used for creating temporary directories.
       74  
            */
      -  75  1
           private static int dirCount = 0;
      +  75  2
           private static int dirCount = 0;
       76  
           /**
       77  
            * The parent directory for the individual directories per archive.
       78  
            */
      -  79  4
           private File tempFileLocation = null;
      +  79  12
           private File tempFileLocation = null;
       80  
           /**
       81  
            * The max scan depth that the analyzer will recursively extract nested archives.
       82  
            */
      -  83  1
           private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3);
      +  83  2
           private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3);
       84  
           /**
       85  
            * Tracks the current scan/extraction depth for nested archives.
       86  
            */
      -  87  4
           private int scanDepth = 0;
      +  87  12
           private int scanDepth = 0;
       88  
       
       89   @@ -203,14 +203,14 @@
            * The phase that this analyzer is intended to run in.
       96  
            */
      -  97  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
      +  97  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
       98  
           /**
       99  
            * The set of things we can handle with Zip methods
       100  
            */
      -  101  1
           private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
      +  101  2
           private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
       102  
           /**
       103   @@ -219,7 +219,7 @@
            * explicitly handled in {@link #extractFiles(File, File, Engine)}.
       105  
            */
      -  106  1
           private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2");
      +  106  2
           private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2");
       107  
       
       108   @@ -228,19 +228,19 @@
            * Detects files with extensions to remove from the engine's collection of dependencies.
       110  
            */
      -  111  1
           private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2")
      -  112  1
                   .build();
      +  111  2
           private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2")
      +  112  2
                   .build();
       113  
       
       114  
           static {
      -  115  1
               final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
      -  116  1
               if (additionalZipExt != null) {
      +  115  2
               final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
      +  116  2
               if (additionalZipExt != null) {
       117  0
                   final String[] ext = additionalZipExt.split("\\s*,\\s*");
       118  0
                   Collections.addAll(ZIPPABLES, ext);
       119  
               }
      -  120  1
               EXTENSIONS.addAll(ZIPPABLES);
      +  120  2
               EXTENSIONS.addAll(ZIPPABLES);
       121  
           }
       122   @@ -251,14 +251,14 @@
            * The file filter used to filter supported files.
       125  
            */
      -  126  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      +  126  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
       127  
       
       128  
           @Override
       129  
           protected FileFilter getFileFilter() {
      -  130  853
               return FILTER;
      +  130  1718
               return FILTER;
       131  
           }
       132   @@ -269,7 +269,7 @@
            * Detects files with .zip extension.
       135  
            */
      -  136  1
           private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build();
      +  136  2
           private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build();
       137  
       
       138   @@ -286,7 +286,7 @@
           @Override
       144  
           public String getName() {
      -  145  4
               return ANALYZER_NAME;
      +  145  32
               return ANALYZER_NAME;
       146  
           }
       147   @@ -305,7 +305,7 @@
           @Override
       154  
           public AnalysisPhase getAnalysisPhase() {
      -  155  3
               return ANALYSIS_PHASE;
      +  155  8
               return ANALYSIS_PHASE;
       156  
           }
       157   @@ -326,7 +326,7 @@
           @Override
       165  
           protected String getAnalyzerEnabledSettingKey() {
      -  166  4
               return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED;
      +  166  12
               return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED;
       167  
           }
       168   @@ -345,19 +345,19 @@
           @Override
       175  
           public void initializeFileTypeAnalyzer() throws Exception {
      -  176  1
               final File baseDir = Settings.getTempDirectory();
      -  177  1
               tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      -  178  1
               if (!tempFileLocation.delete()) {
      +  176  2
               final File baseDir = Settings.getTempDirectory();
      +  177  2
               tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      +  178  2
               if (!tempFileLocation.delete()) {
       179  0
                   final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
       180  0
                   throw new AnalysisException(msg);
       181  
               }
      -  182  1
               if (!tempFileLocation.mkdirs()) {
      +  182  2
               if (!tempFileLocation.mkdirs()) {
       183  0
                   final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
       184  0
                   throw new AnalysisException(msg);
       185  
               }
      -  186  1
           }
      +  186  2
           }
       187  
       
       188   @@ -374,10 +374,10 @@
           @Override
       194  
           public void close() throws Exception {
      -  195  1
               if (tempFileLocation != null && tempFileLocation.exists()) {
      -  196  1
                   LOGGER.debug("Attempting to delete temporary files");
      -  197  1
                   final boolean success = FileUtils.delete(tempFileLocation);
      -  198  1
                   if (!success && tempFileLocation.exists()) {
      +  195  4
               if (tempFileLocation != null && tempFileLocation.exists()) {
      +  196  2
                   LOGGER.debug("Attempting to delete temporary files");
      +  197  2
                   final boolean success = FileUtils.delete(tempFileLocation);
      +  198  2
                   if (!success && tempFileLocation.exists()) {
       199  0
                       final String[] l = tempFileLocation.list();
       200  0
                       if (l != null && l.length > 0) {
       201  0
                           LOGGER.warn("Failed to delete some temporary files, see the log for more details");
      @@ -387,7 +387,7 @@
                   }
       204  
               }
      -  205  1
           }
      +  205  4
           }
       206  
       
       207   @@ -410,15 +410,15 @@
           @Override
       216  
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      -  217  2
               final File f = new File(dependency.getActualFilePath());
      -  218  2
               final File tmpDir = getNextTempDirectory();
      -  219  2
               extractFiles(f, tmpDir, engine);
      +  217  4
               final File f = new File(dependency.getActualFilePath());
      +  218  4
               final File tmpDir = getNextTempDirectory();
      +  219  4
               extractFiles(f, tmpDir, engine);
       220  
       
       221  
               //make a copy
      -  222  2
               final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpDir);
      -  223  2
               if (!dependencySet.isEmpty()) {
      +  222  4
               final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpDir);
      +  223  4
               if (!dependencySet.isEmpty()) {
       224  0
                   for (Dependency d : dependencySet) {
       225  
                       //fix the dependency's display name and path
      @@ -445,13 +445,13 @@  242  0
                   }
       243  
               }
      -  244  2
               if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) {
      +  244  4
               if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) {
       245  0
                   addDisguisedJarsToDependencies(dependency, engine);
       246  0
                   engine.getDependencies().remove(dependency);
       247  
               }
      -  248  2
               Collections.sort(engine.getDependencies());
      -  249  2
           }
      +  248  4
               Collections.sort(engine.getDependencies());
      +  249  4
           }
       250  
       
       251   @@ -508,7 +508,7 @@
            * An empty dependency set.
       286  
            */
      -  287  1
           private static final Set<Dependency> EMPTY_DEPENDENCY_SET = Collections.emptySet();
      +  287  2
           private static final Set<Dependency> EMPTY_DEPENDENCY_SET = Collections.emptySet();
       288  
       
       289   @@ -527,23 +527,23 @@
            */
       296  
           private static Set<Dependency> findMoreDependencies(Engine engine, File file) {
      -  297  2
               final List<Dependency> before = new ArrayList<Dependency>(engine.getDependencies());
      -  298  2
               engine.scan(file);
      -  299  2
               final List<Dependency> after = engine.getDependencies();
      -  300  2
               final boolean sizeChanged = before.size() != after.size();
      +  297  4
               final List<Dependency> before = new ArrayList<Dependency>(engine.getDependencies());
      +  298  4
               engine.scan(file);
      +  299  4
               final List<Dependency> after = engine.getDependencies();
      +  300  4
               final boolean sizeChanged = before.size() != after.size();
       301  
               final Set<Dependency> newDependencies;
      -  302  2
               if (sizeChanged) {
      +  302  4
               if (sizeChanged) {
       303  
                   //get the new dependencies
       304  0
                   newDependencies = new HashSet<Dependency>(after);
       305  0
                   newDependencies.removeAll(before);
       306  
               } else {
      -  307  2
                   newDependencies = EMPTY_DEPENDENCY_SET;
      +  307  4
                   newDependencies = EMPTY_DEPENDENCY_SET;
       308  
               }
      -  309  2
               return newDependencies;
      +  309  4
               return newDependencies;
       310  
           }
       311   @@ -562,20 +562,20 @@
            */
       318  
           private File getNextTempDirectory() throws AnalysisException {
      -  319  2
               dirCount += 1;
      -  320  2
               final File directory = new File(tempFileLocation, String.valueOf(dirCount));
      +  319  4
               dirCount += 1;
      +  320  4
               final File directory = new File(tempFileLocation, String.valueOf(dirCount));
       321  
               //getting an exception for some directories not being able to be created; might be because the directory already exists?
      -  322  2
               if (directory.exists()) {
      +  322  4
               if (directory.exists()) {
       323  0
                   return getNextTempDirectory();
       324  
               }
      -  325  2
               if (!directory.mkdirs()) {
      +  325  4
               if (!directory.mkdirs()) {
       326  0
                   final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
       327  0
                   throw new AnalysisException(msg);
       328  
               }
      -  329  2
               return directory;
      +  329  4
               return directory;
       330  
           }
       331   @@ -598,21 +598,21 @@
            */
       340  
           private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException {
      -  341  2
               if (archive != null && destination != null) {
      +  341  4
               if (archive != null && destination != null) {
       342  
                   FileInputStream fis;
       343  
                   try {
      -  344  2
                       fis = new FileInputStream(archive);
      +  344  4
                       fis = new FileInputStream(archive);
       345  0
                   } catch (FileNotFoundException ex) {
       346  0
                       LOGGER.debug("", ex);
       347  0
                       throw new AnalysisException("Archive file was not found.", ex);
      -  348  2
                   }
      -  349  2
                   final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
      +  348  4
                   }
      +  349  4
                   final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
       350  
                   try {
      -  351  2
                       if (ZIPPABLES.contains(archiveExt)) {
      -  352  2
                           extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
      +  351  4
                       if (ZIPPABLES.contains(archiveExt)) {
      +  352  4
                           extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
       353  0
                       } else if ("tar".equals(archiveExt)) {
       354  0
                           extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
       355  0
                       } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) {
      @@ -639,11 +639,11 @@  373  0
                       LOGGER.debug("", ex);
       374  
                   } finally {
      -  375  2
                       close(fis);
      -  376  2
                   }
      +  375  4
                       close(fis);
      +  376  4
                   }
       377  
               }
      -  378  2
           }
      +  378  4
           }
       379  
       
       380   @@ -668,26 +668,26 @@
               ArchiveEntry entry;
       390  
               try {
      -  391  887
                   while ((entry = input.getNextEntry()) != null) {
      -  392  885
                       final File file = new File(destination, entry.getName());
      -  393  885
                       if (entry.isDirectory()) {
      -  394  36
                           if (!file.exists() && !file.mkdirs()) {
      +  391  1774
                   while ((entry = input.getNextEntry()) != null) {
      +  392  1770
                       final File file = new File(destination, entry.getName());
      +  393  1770
                       if (entry.isDirectory()) {
      +  394  72
                           if (!file.exists() && !file.mkdirs()) {
       395  0
                               final String msg = String.format("Unable to create directory '%s'.", file.getAbsolutePath());
       396  0
                               throw new AnalysisException(msg);
       397  
                           }
      -  398  849
                       } else if (engine.accept(file)) {
      +  398  1698
                       } else if (engine.accept(file)) {
       399  0
                           extractAcceptedFile(input, file);
       400  
                       }
      -  401  885
                   }
      +  401  1770
                   }
       402  0
               } catch (Throwable ex) {
       403  0
                   throw new ArchiveExtractionException(ex);
       404  
               } finally {
      -  405  2
                   close(input);
      -  406  2
               }
      -  407  2
           }
      +  405  4
                   close(input);
      +  406  4
               }
      +  407  4
           }
       408  
       
       409   @@ -780,16 +780,16 @@
            */
       469  
           private static void close(Closeable closeable) {
      -  470  4
               if (null != closeable) {
      +  470  8
               if (null != closeable) {
       471  
                   try {
      -  472  4
                       closeable.close();
      +  472  8
                       closeable.close();
       473  0
                   } catch (IOException ex) {
       474  0
                       LOGGER.trace("", ex);
      -  475  4
                   }
      +  475  8
                   }
       476  
               }
      -  477  4
           }
      +  477  8
           }
       478  
       
       479   @@ -843,6 +843,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html index 102acf7bb..85b6114a6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html @@ -121,7 +121,7 @@
        *
       52  
        */
      -  53  9
       public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
      +  53  22
       public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
       54  
       
       55   @@ -138,21 +138,21 @@
            * The analysis phase
       61  
            */
      -  62  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  62  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       63  
           /**
       64  
            * The list of supported extensions
       65  
            */
      -  66  1
           private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"};
      +  66  2
           private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"};
       67  
           /**
       68  
            * The temp value for GrokAssembly.exe
       69  
            */
      -  70  9
           private File grokAssemblyExe = null;
      +  70  22
           private File grokAssemblyExe = null;
       71  
           /**
       72   @@ -167,7 +167,7 @@
            * Logger
       77  
            */
      -  78  1
           private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class);
      +  78  2
           private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class);
       79  
       
       80   @@ -184,8 +184,8 @@
           private List<String> buildArgumentList() {
       86  
               // Use file.separator as a wild guess as to whether this is Windows
      -  87  8
               final List<String> args = new ArrayList<String>();
      -  88  8
               if (!"\\".equals(System.getProperty("file.separator"))) {
      +  87  16
               final List<String> args = new ArrayList<String>();
      +  88  16
               if (!"\\".equals(System.getProperty("file.separator"))) {
       89  0
                   if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) {
       90  0
                       args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH));
       91   @@ -195,10 +195,10 @@
                   }
       94  
               }
      -  95  8
               args.add(grokAssemblyExe.getPath());
      +  95  16
               args.add(grokAssemblyExe.getPath());
       96  
       
      -  97  8
               return args;
      +  97  16
               return args;
       98  
           }
       99   @@ -223,84 +223,84 @@
           public void analyzeFileType(Dependency dependency, Engine engine)
       109  
                   throws AnalysisException {
      -  110  3
               if (grokAssemblyExe == null) {
      +  110  6
               if (grokAssemblyExe == null) {
       111  0
                   LOGGER.warn("GrokAssembly didn't get deployed");
       112  0
                   return;
       113  
               }
       114  
       
      -  115  3
               final List<String> args = buildArgumentList();
      -  116  3
               args.add(dependency.getActualFilePath());
      -  117  3
               final ProcessBuilder pb = new ProcessBuilder(args);
      -  118  3
               Document doc = null;
      +  115  6
               final List<String> args = buildArgumentList();
      +  116  6
               args.add(dependency.getActualFilePath());
      +  117  6
               final ProcessBuilder pb = new ProcessBuilder(args);
      +  118  6
               Document doc = null;
       119  
               try {
      -  120  3
                   final Process proc = pb.start();
      +  120  6
                   final Process proc = pb.start();
       121  
       
      -  122  3
                   doc = builder.parse(proc.getInputStream());
      +  122  6
                   doc = builder.parse(proc.getInputStream());
       123  
       
       124  
                   // Try evacuating the error stream
      -  125  3
                   final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8");
      -  126  3
                   if (null != errorStream && !errorStream.isEmpty()) {
      +  125  6
                   final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8");
      +  126  6
                   if (null != errorStream && !errorStream.isEmpty()) {
       127  0
                       LOGGER.warn("Error from GrokAssembly: {}", errorStream);
       128  
                   }
       129  
       
      -  130  3
                   int rc = 0;
      +  130  6
                   int rc = 0;
       131  
                   try {
      -  132  3
                       rc = proc.waitFor();
      +  132  6
                       rc = proc.waitFor();
       133  0
                   } catch (InterruptedException ie) {
       134  0
                       return;
      -  135  3
                   }
      -  136  3
                   if (rc == 3) {
      +  135  6
                   }
      +  136  6
                   if (rc == 3) {
       137  0
                       LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check",
       138  0
                               dependency.getActualFilePath());
       139  0
                       return;
      -  140  3
                   } else if (rc != 0) {
      -  141  1
                       LOGGER.warn("Return code {} from GrokAssembly", rc);
      +  140  6
                   } else if (rc != 0) {
      +  141  2
                       LOGGER.warn("Return code {} from GrokAssembly", rc);
       142  
                   }
       143  
       
      -  144  3
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      +  144  6
                   final XPath xpath = XPathFactory.newInstance().newXPath();
       145  
       
       146  
                   // First, see if there was an error
      -  147  3
                   final String error = xpath.evaluate("/assembly/error", doc);
      -  148  3
                   if (error != null && !error.isEmpty()) {
      -  149  1
                       throw new AnalysisException(error);
      +  147  6
                   final String error = xpath.evaluate("/assembly/error", doc);
      +  148  6
                   if (error != null && !error.isEmpty()) {
      +  149  2
                       throw new AnalysisException(error);
       150  
                   }
       151  
       
      -  152  2
                   final String version = xpath.evaluate("/assembly/version", doc);
      -  153  2
                   if (version != null) {
      -  154  2
                       dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version",
      +  152  4
                   final String version = xpath.evaluate("/assembly/version", doc);
      +  153  4
                   if (version != null) {
      +  154  4
                       dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version",
       155  
                               version, Confidence.HIGHEST));
       156  
                   }
       157  
       
      -  158  2
                   final String vendor = xpath.evaluate("/assembly/company", doc);
      -  159  2
                   if (vendor != null) {
      -  160  2
                       dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor",
      +  158  4
                   final String vendor = xpath.evaluate("/assembly/company", doc);
      +  159  4
                   if (vendor != null) {
      +  160  4
                       dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor",
       161  
                               vendor, Confidence.HIGH));
       162  
                   }
       163  
       
      -  164  2
                   final String product = xpath.evaluate("/assembly/product", doc);
      -  165  2
                   if (product != null) {
      -  166  2
                       dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product",
      +  164  4
                   final String product = xpath.evaluate("/assembly/product", doc);
      +  165  4
                   if (product != null) {
      +  166  4
                       dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product",
       167  
                               product, Confidence.HIGH));
       168   @@ -315,8 +315,8 @@  175  
                   // This shouldn't happen
       176  0
                   throw new AnalysisException(xpe);
      -  177  2
               }
      -  178  2
           }
      +  177  4
               }
      +  178  4
           }
       179  
       
       180   @@ -333,43 +333,43 @@
           @Override
       186  
           public void initializeFileTypeAnalyzer() throws Exception {
      -  187  5
               final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
      -  188  5
               FileOutputStream fos = null;
      -  189  5
               InputStream is = null;
      +  187  10
               final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
      +  188  10
               FileOutputStream fos = null;
      +  189  10
               InputStream is = null;
       190  
               try {
      -  191  5
                   fos = new FileOutputStream(tempFile);
      -  192  5
                   is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
      -  193  5
                   IOUtils.copy(is, fos);
      +  191  10
                   fos = new FileOutputStream(tempFile);
      +  192  10
                   is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
      +  193  10
                   IOUtils.copy(is, fos);
       194  
       
      -  195  5
                   grokAssemblyExe = tempFile;
      +  195  10
                   grokAssemblyExe = tempFile;
       196  
                   // Set the temp file to get deleted when we're done
      -  197  5
                   grokAssemblyExe.deleteOnExit();
      -  198  5
                   LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath());
      +  197  10
                   grokAssemblyExe.deleteOnExit();
      +  198  10
                   LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath());
       199  0
               } catch (IOException ioe) {
       200  0
                   this.setEnabled(false);
       201  0
                   LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage());
       202  0
                   throw new AnalysisException("Could not extract GrokAssembly.exe", ioe);
       203  
               } finally {
      -  204  5
                   if (fos != null) {
      +  204  10
                   if (fos != null) {
       205  
                       try {
      -  206  5
                           fos.close();
      +  206  10
                           fos.close();
       207  0
                       } catch (Throwable e) {
       208  0
                           LOGGER.debug("Error closing output stream");
      -  209  5
                       }
      +  209  10
                       }
       210  
                   }
      -  211  5
                   if (is != null) {
      +  211  10
                   if (is != null) {
       212  
                       try {
      -  213  5
                           is.close();
      +  213  10
                           is.close();
       214  0
                       } catch (Throwable e) {
       215  0
                           LOGGER.debug("Error closing input stream");
      -  216  5
                       }
      +  216  10
                       }
       217  
                   }
       218   @@ -378,20 +378,20 @@
       
       220  
               // Now, need to see if GrokAssembly actually runs from this location.
      -  221  5
               final List<String> args = buildArgumentList();
      +  221  10
               final List<String> args = buildArgumentList();
       222  
               try {
      -  223  5
                   final ProcessBuilder pb = new ProcessBuilder(args);
      -  224  5
                   final Process p = pb.start();
      +  223  10
                   final ProcessBuilder pb = new ProcessBuilder(args);
      +  224  10
                   final Process p = pb.start();
       225  
                   // Try evacuating the error stream
      -  226  5
                   IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM);
      +  226  10
                   IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM);
       227  
       
      -  228  5
                   final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
      -  229  5
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      -  230  5
                   final String error = xpath.evaluate("/assembly/error", doc);
      -  231  5
                   if (p.waitFor() != 1 || error == null || error.isEmpty()) {
      +  228  10
                   final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
      +  229  10
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      +  230  10
                   final String error = xpath.evaluate("/assembly/error", doc);
      +  231  10
                   if (p.waitFor() != 1 || error == null || error.isEmpty()) {
       232  0
                       LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details.");
       233  0
                       LOGGER.debug("GrokAssembly.exe is not working properly");
       234  0
                       grokAssemblyExe = null;
      @@ -408,9 +408,9 @@  243  0
                   LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage());
       244  0
                   this.setEnabled(false);
       245  0
                   throw new AnalysisException("An error occurred with the .NET AssemblyAnalyzer", e);
      -  246  5
               }
      -  247  5
               builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      -  248  5
           }
      +  246  10
               }
      +  247  10
               builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      +  248  10
           }
       249  
       
       250   @@ -427,17 +427,17 @@
           @Override
       256  
           public void close() throws Exception {
      -  257  6
               super.close();
      +  257  14
               super.close();
       258  
               try {
      -  259  6
                   if (grokAssemblyExe != null && !grokAssemblyExe.delete()) {
      +  259  14
                   if (grokAssemblyExe != null && !grokAssemblyExe.delete()) {
       260  0
                       grokAssemblyExe.deleteOnExit();
       261  
                   }
       262  0
               } catch (SecurityException se) {
       263  0
                   LOGGER.debug("Can't delete temporary GrokAssembly.exe");
      -  264  6
               }
      -  265  6
           }
      +  264  14
               }
      +  265  14
           }
       266  
       
       267   @@ -446,15 +446,15 @@
            * The File Filter used to filter supported extensions.
       269  
            */
      -  270  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
      -  271  1
                   SUPPORTED_EXTENSIONS).build();
      +  270  4
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
      +  271  2
                   SUPPORTED_EXTENSIONS).build();
       272  
       
       273  
           @Override
       274  
           protected FileFilter getFileFilter() {
      -  275  858
               return FILTER;
      +  275  1728
               return FILTER;
       276  
           }
       277   @@ -473,7 +473,7 @@
           @Override
       284  
           public String getName() {
      -  285  5
               return ANALYZER_NAME;
      +  285  34
               return ANALYZER_NAME;
       286  
           }
       287   @@ -492,7 +492,7 @@
           @Override
       294  
           public AnalysisPhase getAnalysisPhase() {
      -  295  3
               return ANALYSIS_PHASE;
      +  295  8
               return ANALYSIS_PHASE;
       296  
           }
       297   @@ -511,13 +511,13 @@
           @Override
       304  
           protected String getAnalyzerEnabledSettingKey() {
      -  305  9
               return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED;
      +  305  22
               return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED;
       306  
           }
       307  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html index 8f890c3fc..8ba0b0b1a 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      AutoconfAnalyzer
      90%
      67/74
      76%
      26/34
      3.111
      AutoconfAnalyzer
      90%
      64/71
      76%
      26/34
      3.222
       
      @@ -82,347 +82,350 @@  32  
       import java.io.IOException;
       33   -
       import java.util.ArrayList;
      +
       import java.nio.charset.Charset;
       34   -
       import java.util.List;
      +
       import java.util.ArrayList;
       35   -
       import java.util.regex.Matcher;
      +
       import java.util.List;
       36   -
       import java.util.regex.Pattern;
      +
       import java.util.regex.Matcher;
       37   -
       
      +
       import java.util.regex.Pattern;
       38   -
       /**
      +
       
       39   -
        * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed,
      +
       /**
       40   -
        * assuming they are generated by Autoconf, and contain certain special package descriptor variables.
      +
        * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed,
       41   -
        *
      +
        * assuming they are generated by Autoconf, and contain certain special package descriptor variables.
       42   -
        * @author Dale Visser
      +
        *
       43   -
        * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a>
      +
        * @author Dale Visser
       44   +
        * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a>
      +  45  
        */
      -  45  10
       public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
       46   -
       
      -  47   -
           /**
      +
       @Experimental
      +  47  24
       public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
       48   -
            * Autoconf output filename.
      +
       
       49   -
            */
      +
           /**
       50   -
           private static final String CONFIGURE = "configure";
      +
            * Autoconf output filename.
       51   -
       
      +
            */
       52   -
           /**
      +
           private static final String CONFIGURE = "configure";
       53   -
            * Autoconf input filename.
      +
       
       54   -
            */
      +
           /**
       55   -
           private static final String CONFIGURE_IN = "configure.in";
      -  56   -
       
      -  57   -
           /**
      -  58  
            * Autoconf input filename.
      +  56   +
            */
      +  57   +
           private static final String CONFIGURE_IN = "configure.in";
      +  58   +
       
       59   -
            */
      +
           /**
       60   -
           private static final String CONFIGURE_AC = "configure.ac";
      +
            * Autoconf input filename.
       61   -
       
      +
            */
       62   -
           /**
      +
           private static final String CONFIGURE_AC = "configure.ac";
       63   -
            * The name of the analyzer.
      +
       
       64   -
            */
      +
           /**
       65   -
           private static final String ANALYZER_NAME = "Autoconf Analyzer";
      +
            * The name of the analyzer.
       66   -
       
      +
            */
       67   -
           /**
      +
           private static final String ANALYZER_NAME = "Autoconf Analyzer";
       68   -
            * The phase that this analyzer is intended to run in.
      +
       
       69   -
            */
      -  70  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +
           /**
      +  70   +
            * The phase that this analyzer is intended to run in.
       71   -
       
      -  72   -
           /**
      +
            */
      +  72  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       73   -
            * The set of file extensions supported by this analyzer.
      +
       
       74   -
            */
      -  75  1
           private static final String[] EXTENSIONS = {"ac", "in"};
      +
           /**
      +  75   +
            * The set of file extensions supported by this analyzer.
       76   -
       
      -  77   -
           /**
      +
            */
      +  77  2
           private static final String[] EXTENSIONS = {"ac", "in"};
       78   -
            * Matches AC_INIT variables in the output configure script.
      +
       
       79   -
            */
      -  80  1
           private static final Pattern PACKAGE_VAR = Pattern.compile(
      +
           /**
      +  80   +
            * Matches AC_INIT variables in the output configure script.
       81   -
                   "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
      -  82   -
       
      +
            */
      +  82  2
           private static final Pattern PACKAGE_VAR = Pattern.compile(
       83   -
           /**
      +
                   "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
       84   -
            * Matches AC_INIT statement in configure.ac file.
      +
       
       85   -
            */
      +
           /**
       86   -
           private static final Pattern AC_INIT_PATTERN;
      +
            * Matches AC_INIT statement in configure.ac file.
       87   -
       
      +
            */
       88   -
           static {
      +
           private static final Pattern AC_INIT_PATTERN;
       89   +
       
      +  90   +
           static {
      +  91  
               // each instance of param or sep_param has a capture group
      -  90  1
               final String param = "\\[{0,2}(.+?)\\]{0,2}";
      -  91  1
               final String sepParam = "\\s*,\\s*" + param;
      -  92   -
               // Group 1: Package
      -  93   -
               // Group 2: Version
      +  92  2
               final String param = "\\[{0,2}(.+?)\\]{0,2}";
      +  93  2
               final String sepParam = "\\s*,\\s*" + param;
       94   -
               // Group 3: optional
      +
               // Group 1: Package
       95   -
               // Group 4: Bug report address (if it exists)
      +
               // Group 2: Version
       96   -
               // Group 5: optional
      +
               // Group 3: optional
       97   -
               // Group 6: Tarname (if it exists)
      +
               // Group 4: Bug report address (if it exists)
       98   -
               // Group 7: optional
      +
               // Group 5: optional
       99   -
               // Group 8: URL (if it exists)
      -  100  1
               AC_INIT_PATTERN = Pattern.compile(String.format(
      +
               // Group 6: Tarname (if it exists)
      +  100   +
               // Group 7: optional
       101   -
                       "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam,
      -  102   -
                       sepParam, sepParam, sepParam), Pattern.DOTALL
      +
               // Group 8: URL (if it exists)
      +  102  2
               AC_INIT_PATTERN = Pattern.compile(String.format(
       103   -
                       | Pattern.CASE_INSENSITIVE);
      +
                       "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam,
       104   -
           }
      +
                       sepParam, sepParam, sepParam), Pattern.DOTALL
       105   -
       
      +
                       | Pattern.CASE_INSENSITIVE);
       106   -
           /**
      +
           }
       107   -
            * The file filter used to determine which files this analyzer supports.
      +
       
       108   -
            */
      -  109  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions(
      -  110  1
                   EXTENSIONS).build();
      -  111   -
       
      -  112  
           /**
      +  109   +
            * The file filter used to determine which files this analyzer supports.
      +  110   +
            */
      +  111  4
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions(
      +  112  2
                   EXTENSIONS).build();
       113   -
            * Returns the FileFilter
      +
       
       114   -
            *
      +
           /**
       115   -
            * @return the FileFilter
      +
            * Returns the FileFilter
       116   -
            */
      +
            *
       117   -
           @Override
      +
            * @return the FileFilter
       118   -
           protected FileFilter getFileFilter() {
      -  119  856
               return FILTER;
      +
            */
      +  119   +
           @Override
       120   -
           }
      -  121   -
       
      +
           protected FileFilter getFileFilter() {
      +  121  1724
               return FILTER;
       122   -
           /**
      +
           }
       123   -
            * Returns the name of the analyzer.
      +
       
       124   -
            *
      +
           /**
       125   -
            * @return the name of the analyzer.
      +
            * Returns the name of the analyzer.
       126   -
            */
      +
            *
       127   -
           @Override
      +
            * @return the name of the analyzer.
       128   -
           public String getName() {
      -  129  5
               return ANALYZER_NAME;
      +
            */
      +  129   +
           @Override
       130   -
           }
      -  131   -
       
      +
           public String getName() {
      +  131  30
               return ANALYZER_NAME;
       132   -
           /**
      +
           }
       133   -
            * Returns the phase that the analyzer is intended to run in.
      +
       
       134   -
            *
      +
           /**
       135   -
            * @return the phase that the analyzer is intended to run in.
      +
            * Returns the phase that the analyzer is intended to run in.
       136   -
            */
      +
            *
       137   -
           @Override
      +
            * @return the phase that the analyzer is intended to run in.
       138   -
           public AnalysisPhase getAnalysisPhase() {
      -  139  3
               return ANALYSIS_PHASE;
      +
            */
      +  139   +
           @Override
       140   -
           }
      -  141   -
       
      +
           public AnalysisPhase getAnalysisPhase() {
      +  141  8
               return ANALYSIS_PHASE;
       142   -
           /**
      -  143   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      -  144   -
            *
      -  145   -
            * @return the analyzer's enabled property setting key
      -  146   -
            */
      -  147   -
           @Override
      -  148   -
           protected String getAnalyzerEnabledSettingKey() {
      -  149  10
               return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
      -  150  
           }
      -  151   +  143  
       
      -  152   +  144   +
           /**
      +  145   +
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +  146   +
            *
      +  147   +
            * @return the analyzer's enabled property setting key
      +  148   +
            */
      +  149  
           @Override
      +  150   +
           protected String getAnalyzerEnabledSettingKey() {
      +  151  24
               return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
      +  152   +
           }
       153   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +
       
       154   +
           @Override
      +  155   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  156  
                   throws AnalysisException {
      -  155  4
               final File actualFile = dependency.getActualFile();
      -  156  4
               final String name = actualFile.getName();
      -  157  4
               if (name.startsWith(CONFIGURE)) {
      -  158  4
                   final File parent = actualFile.getParentFile();
      -  159  4
                   final String parentName = parent.getName();
      -  160  4
                   dependency.setDisplayFileName(parentName + "/" + name);
      -  161  4
                   final boolean isOutputScript = CONFIGURE.equals(name);
      -  162  4
                   if (isOutputScript || CONFIGURE_AC.equals(name)
      -  163  0
                           || CONFIGURE_IN.equals(name)) {
      -  164  4
                       final String contents = getFileContents(actualFile);
      -  165  4
                       if (!contents.isEmpty()) {
      -  166  4
                           if (isOutputScript) {
      -  167  2
                               extractConfigureScriptEvidence(dependency, name,
      -  168   +  157  8
               final File actualFile = dependency.getActualFile();
      +  158  8
               final String name = actualFile.getName();
      +  159  8
               if (name.startsWith(CONFIGURE)) {
      +  160  8
                   final File parent = actualFile.getParentFile();
      +  161  8
                   final String parentName = parent.getName();
      +  162  8
                   dependency.setDisplayFileName(parentName + "/" + name);
      +  163  8
                   final boolean isOutputScript = CONFIGURE.equals(name);
      +  164  8
                   if (isOutputScript || CONFIGURE_AC.equals(name)
      +  165  0
                           || CONFIGURE_IN.equals(name)) {
      +  166  8
                       final String contents = getFileContents(actualFile);
      +  167  8
                       if (!contents.isEmpty()) {
      +  168  8
                           if (isOutputScript) {
      +  169  4
                               extractConfigureScriptEvidence(dependency, name,
      +  170  
                                       contents);
      -  169   -
                           } else {
      -  170  2
                               gatherEvidence(dependency, name, contents);
       171   -
                           }
      -  172   -
                       }
      +
                           } else {
      +  172  4
                               gatherEvidence(dependency, name, contents);
       173   -
                   }
      -  174  4
               } else {
      -  175   -
                   // copy, alter and set in case some other thread is iterating over
      -  176  0
                   final List<Dependency> dependencies = new ArrayList<Dependency>(
      -  177  0
                           engine.getDependencies());
      -  178  0
                   dependencies.remove(dependency);
      -  179  0
                   engine.setDependencies(dependencies);
      -  180   -
               }
      -  181  4
           }
      -  182   -
       
      -  183   -
           /**
      -  184   -
            * Extracts evidence from the configuration.
      -  185   -
            *
      -  186   -
            * @param dependency the dependency being analyzed
      -  187   -
            * @param name the name of the source of evidence
      -  188   -
            * @param contents the contents to analyze for evidence
      -  189   -
            */
      -  190   -
           private void extractConfigureScriptEvidence(Dependency dependency,
      -  191   -
                   final String name, final String contents) {
      -  192  2
               final Matcher matcher = PACKAGE_VAR.matcher(contents);
      -  193  20
               while (matcher.find()) {
      -  194  18
                   final String variable = matcher.group(1);
      -  195  18
                   final String value = matcher.group(2);
      -  196  18
                   if (!value.isEmpty()) {
      -  197  14
                       if (variable.endsWith("NAME")) {
      -  198  4
                           dependency.getProductEvidence().addEvidence(name, variable,
      -  199   -
                                   value, Confidence.HIGHEST);
      -  200  10
                       } else if ("VERSION".equals(variable)) {
      -  201  2
                           dependency.getVersionEvidence().addEvidence(name, variable,
      -  202   -
                                   value, Confidence.HIGHEST);
      -  203  8
                       } else if ("BUGREPORT".equals(variable)) {
      -  204  1
                           dependency.getVendorEvidence().addEvidence(name, variable,
      -  205   -
                                   value, Confidence.HIGH);
      -  206  7
                       } else if ("URL".equals(variable)) {
      -  207  1
                           dependency.getVendorEvidence().addEvidence(name, variable,
      -  208   -
                                   value, Confidence.HIGH);
      -  209   +
                           }
      +  174  
                       }
      -  210   +  175  
                   }
      -  211  18
               }
      -  212  2
           }
      -  213   +  176  8
               } else {
      +  177   +
                   // copy, alter and set in case some other thread is iterating over
      +  178  0
                   final List<Dependency> dependencies = new ArrayList<Dependency>(
      +  179  0
                           engine.getDependencies());
      +  180  0
                   dependencies.remove(dependency);
      +  181  0
                   engine.setDependencies(dependencies);
      +  182   +
               }
      +  183  8
           }
      +  184  
       
      -  214   +  185  
           /**
      -  215   -
            * Retrieves the contents of a given file.
      -  216   +  186   +
            * Extracts evidence from the configuration.
      +  187  
            *
      -  217   -
            * @param actualFile the file to read
      -  218   -
            * @return the contents of the file
      -  219   -
            * @throws AnalysisException thrown if there is an IO Exception
      -  220   +  188   +
            * @param dependency the dependency being analyzed
      +  189   +
            * @param name the name of the source of evidence
      +  190   +
            * @param contents the contents to analyze for evidence
      +  191  
            */
      +  192   +
           private void extractConfigureScriptEvidence(Dependency dependency,
      +  193   +
                   final String name, final String contents) {
      +  194  4
               final Matcher matcher = PACKAGE_VAR.matcher(contents);
      +  195  40
               while (matcher.find()) {
      +  196  36
                   final String variable = matcher.group(1);
      +  197  36
                   final String value = matcher.group(2);
      +  198  36
                   if (!value.isEmpty()) {
      +  199  28
                       if (variable.endsWith("NAME")) {
      +  200  8
                           dependency.getProductEvidence().addEvidence(name, variable,
      +  201   +
                                   value, Confidence.HIGHEST);
      +  202  20
                       } else if ("VERSION".equals(variable)) {
      +  203  4
                           dependency.getVersionEvidence().addEvidence(name, variable,
      +  204   +
                                   value, Confidence.HIGHEST);
      +  205  16
                       } else if ("BUGREPORT".equals(variable)) {
      +  206  2
                           dependency.getVendorEvidence().addEvidence(name, variable,
      +  207   +
                                   value, Confidence.HIGH);
      +  208  14
                       } else if ("URL".equals(variable)) {
      +  209  2
                           dependency.getVendorEvidence().addEvidence(name, variable,
      +  210   +
                                   value, Confidence.HIGH);
      +  211   +
                       }
      +  212   +
                   }
      +  213  36
               }
      +  214  4
           }
      +  215   +
       
      +  216   +
           /**
      +  217   +
            * Retrieves the contents of a given file.
      +  218   +
            *
      +  219   +
            * @param actualFile the file to read
      +  220   +
            * @return the contents of the file
       221   -
           private String getFileContents(final File actualFile)
      +
            * @throws AnalysisException thrown if there is an IO Exception
       222   -
                   throws AnalysisException {
      -  223  4
               String contents = "";
      +
            */
      +  223   +
           private String getFileContents(final File actualFile)
       224   +
                   throws AnalysisException {
      +  225  
               try {
      -  225  4
                   contents = FileUtils.readFileToString(actualFile).trim();
      -  226  0
               } catch (IOException e) {
      -  227  0
                   throw new AnalysisException(
      -  228   +  226  8
                   return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim();
      +  227  0
               } catch (IOException e) {
      +  228  0
                   throw new AnalysisException(
      +  229  
                           "Problem occurred while reading dependency file.", e);
      -  229  4
               }
      -  230  4
               return contents;
      +  230   +
               }
       231  
           }
       232   @@ -445,32 +448,32 @@
           private void gatherEvidence(Dependency dependency, final String name,
       241  
                   String contents) {
      -  242  2
               final Matcher matcher = AC_INIT_PATTERN.matcher(contents);
      -  243  2
               if (matcher.find()) {
      -  244  2
                   final EvidenceCollection productEvidence = dependency
      -  245  2
                           .getProductEvidence();
      -  246  2
                   productEvidence.addEvidence(name, "Package", matcher.group(1),
      +  242  4
               final Matcher matcher = AC_INIT_PATTERN.matcher(contents);
      +  243  4
               if (matcher.find()) {
      +  244  4
                   final EvidenceCollection productEvidence = dependency
      +  245  4
                           .getProductEvidence();
      +  246  4
                   productEvidence.addEvidence(name, "Package", matcher.group(1),
       247  
                           Confidence.HIGHEST);
      -  248  4
                   dependency.getVersionEvidence().addEvidence(name,
      -  249  2
                           "Package Version", matcher.group(2), Confidence.HIGHEST);
      -  250  2
                   final EvidenceCollection vendorEvidence = dependency
      -  251  2
                           .getVendorEvidence();
      -  252  2
                   if (null != matcher.group(3)) {
      -  253  4
                       vendorEvidence.addEvidence(name, "Bug report address",
      -  254  2
                               matcher.group(4), Confidence.HIGH);
      +  248  8
                   dependency.getVersionEvidence().addEvidence(name,
      +  249  4
                           "Package Version", matcher.group(2), Confidence.HIGHEST);
      +  250  4
                   final EvidenceCollection vendorEvidence = dependency
      +  251  4
                           .getVendorEvidence();
      +  252  4
                   if (null != matcher.group(3)) {
      +  253  8
                       vendorEvidence.addEvidence(name, "Bug report address",
      +  254  4
                               matcher.group(4), Confidence.HIGH);
       255  
                   }
      -  256  2
                   if (null != matcher.group(5)) {
      -  257  1
                       productEvidence.addEvidence(name, "Tarname", matcher.group(6),
      +  256  4
                   if (null != matcher.group(5)) {
      +  257  2
                       productEvidence.addEvidence(name, "Tarname", matcher.group(6),
       258  
                               Confidence.HIGH);
       259  
                   }
      -  260  2
                   if (null != matcher.group(7)) {
      -  261  1
                       final String url = matcher.group(8);
      -  262  1
                       if (UrlStringUtils.isUrl(url)) {
      -  263  1
                           vendorEvidence.addEvidence(name, "URL", url,
      +  260  4
                   if (null != matcher.group(7)) {
      +  261  2
                       final String url = matcher.group(8);
      +  262  2
                       if (UrlStringUtils.isUrl(url)) {
      +  263  2
                           vendorEvidence.addEvidence(name, "URL", url,
       264  
                                   Confidence.HIGH);
       265   @@ -479,7 +482,7 @@
                   }
       267  
               }
      -  268  2
           }
      +  268  4
           }
       269  
       
       270   @@ -498,11 +501,11 @@
           protected void initializeFileTypeAnalyzer() throws Exception {
       277  
               // No initialization needed.
      -  278  6
           }
      +  278  12
           }
       279  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html index 15d019969..2f52b3b18 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html @@ -88,340 +88,344 @@  35  
       import java.io.UnsupportedEncodingException;
       36   -
       import java.security.MessageDigest;
      +
       import java.nio.charset.Charset;
       37   -
       import java.security.NoSuchAlgorithmException;
      +
       import java.security.MessageDigest;
       38   -
       import java.util.regex.Matcher;
      +
       import java.security.NoSuchAlgorithmException;
       39   -
       import java.util.regex.Pattern;
      +
       import java.util.regex.Matcher;
       40   -
       
      +
       import java.util.regex.Pattern;
       41   -
       /**
      +
       
       42   -
        * <p>
      +
       /**
       43   -
        * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p>
      -  44  
        * <p>
      +  44   +
        * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p>
       45   -
        * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version
      +
        * <p>
       46   -
        * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert
      +
        * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version
       47   -
        * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be
      +
        * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert
       48   -
        * identified.</p>
      +
        * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be
       49   -
        *
      +
        * identified.</p>
       50   -
        * @author Dale Visser
      +
        *
       51   +
        * @author Dale Visser
      +  52  
        */
      -  52  9
       public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
       53   -
       
      -  54   -
           /**
      +
       @Experimental
      +  54  22
       public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
       55   -
            * The logger.
      +
       
       56   -
            */
      -  57  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class);
      +
           /**
      +  57   +
            * The logger.
       58   -
       
      -  59   -
           /**
      +
            */
      +  59  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class);
       60   -
            * Used when compiling file scanning regex patterns.
      +
       
       61   -
            */
      +
           /**
       62   -
           private static final int REGEX_OPTIONS = Pattern.DOTALL
      +
            * Used when compiling file scanning regex patterns.
       63   -
                   | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
      -  64   -
       
      -  65   -
           /**
      -  66   -
            * Regex to extract the product information.
      -  67  
            */
      -  68  1
           private static final Pattern PROJECT = Pattern.compile(
      -  69   -
                   "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS);
      -  70   +  64   +
           private static final int REGEX_OPTIONS = Pattern.DOTALL
      +  65   +
                   | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
      +  66  
       
      -  71   +  67  
           /**
      +  68   +
            * Regex to extract the product information.
      +  69   +
            */
      +  70  2
           private static final Pattern PROJECT = Pattern.compile(
      +  71   +
                   "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS);
       72   -
            * Regex to extract product and version information.
      +
       
       73   -
            *
      +
           /**
       74   -
            * Group 1: Product
      +
            * Regex to extract product and version information.
       75  
            *
       76   -
            * Group 2: Version
      +
            * Group 1: Product
       77   -
            */
      -  78  1
           private static final Pattern SET_VERSION = Pattern
      -  79  1
                   .compile(
      -  80   -
                           "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)",
      -  81   -
                           REGEX_OPTIONS);
      -  82   -
       
      -  83   -
           /**
      -  84   -
            * Detects files that can be analyzed.
      -  85   -
            */
      -  86  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake")
      -  87  1
                   .addFilenames("CMakeLists.txt").build();
      -  88   -
       
      -  89   -
           /**
      -  90   -
            * A reference to SHA1 message digest.
      -  91   -
            */
      -  92  1
           private static MessageDigest sha1 = null;
      -  93   -
       
      -  94   -
           static {
      -  95   -
               try {
      -  96  1
                   sha1 = MessageDigest.getInstance("SHA1");
      -  97  0
               } catch (NoSuchAlgorithmException e) {
      -  98  0
                   LOGGER.error(e.getMessage());
      -  99  1
               }
      -  100  1
           }
      -  101   -
       
      -  102   -
           /**
      -  103   -
            * Returns the name of the CMake analyzer.
      -  104  
            *
      +  78   +
            * Group 2: Version
      +  79   +
            */
      +  80  2
           private static final Pattern SET_VERSION = Pattern
      +  81  2
                   .compile(
      +  82   +
                           "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)",
      +  83   +
                           REGEX_OPTIONS);
      +  84   +
       
      +  85   +
           /**
      +  86   +
            * Detects files that can be analyzed.
      +  87   +
            */
      +  88  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake")
      +  89  2
                   .addFilenames("CMakeLists.txt").build();
      +  90   +
       
      +  91   +
           /**
      +  92   +
            * A reference to SHA1 message digest.
      +  93   +
            */
      +  94  2
           private static MessageDigest sha1 = null;
      +  95   +
       
      +  96   +
           static {
      +  97   +
               try {
      +  98  2
                   sha1 = MessageDigest.getInstance("SHA1");
      +  99  0
               } catch (NoSuchAlgorithmException e) {
      +  100  0
                   LOGGER.error(e.getMessage());
      +  101  2
               }
      +  102  2
           }
      +  103   +
       
      +  104   +
           /**
       105   -
            * @return the name of the analyzer
      +
            * Returns the name of the CMake analyzer.
       106  
            *
       107   -
            */
      +
            * @return the name of the analyzer
       108   -
           @Override
      +
            *
       109   -
           public String getName() {
      -  110  5
               return "CMake Analyzer";
      +
            */
      +  110   +
           @Override
       111   -
           }
      -  112   -
       
      +
           public String getName() {
      +  112  30
               return "CMake Analyzer";
       113   -
           /**
      +
           }
       114   -
            * Tell that we are used for information collection.
      +
       
       115   -
            *
      +
           /**
       116   -
            * @return INFORMATION_COLLECTION
      +
            * Tell that we are used for information collection.
       117   -
            */
      +
            *
       118   -
           @Override
      +
            * @return INFORMATION_COLLECTION
       119   -
           public AnalysisPhase getAnalysisPhase() {
      -  120  3
               return AnalysisPhase.INFORMATION_COLLECTION;
      +
            */
      +  120   +
           @Override
       121   -
           }
      -  122   -
       
      +
           public AnalysisPhase getAnalysisPhase() {
      +  122  8
               return AnalysisPhase.INFORMATION_COLLECTION;
       123   -
           /**
      +
           }
       124   -
            * Returns the set of supported file extensions.
      +
       
       125   -
            *
      +
           /**
       126   -
            * @return the set of supported file extensions
      +
            * Returns the set of supported file extensions.
       127   -
            */
      +
            *
       128   -
           @Override
      +
            * @return the set of supported file extensions
       129   -
           protected FileFilter getFileFilter() {
      -  130  855
               return FILTER;
      +
            */
      +  130   +
           @Override
       131   -
           }
      -  132   -
       
      +
           protected FileFilter getFileFilter() {
      +  132  1722
               return FILTER;
       133   -
           /**
      -  134   -
            * No-op initializer implementation.
      -  135   -
            *
      -  136   -
            * @throws Exception never thrown
      -  137   -
            */
      -  138   -
           @Override
      -  139   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      -  140   -
               // Nothing to do here.
      -  141  5
           }
      -  142   -
       
      -  143   -
           /**
      -  144   -
            * Analyzes python packages and adds evidence to the dependency.
      -  145   -
            *
      -  146   -
            * @param dependency the dependency being analyzed
      -  147   -
            * @param engine the engine being used to perform the scan
      -  148   -
            * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
      -  149   -
            */
      -  150   -
           @Override
      -  151   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  152   -
                   throws AnalysisException {
      -  153  3
               final File file = dependency.getActualFile();
      -  154  3
               final String parentName = file.getParentFile().getName();
      -  155  3
               final String name = file.getName();
      -  156  3
               dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name));
      -  157   -
               String contents;
      -  158   -
               try {
      -  159  3
                   contents = FileUtils.readFileToString(file).trim();
      -  160  0
               } catch (IOException e) {
      -  161  0
                   throw new AnalysisException(
      -  162   -
                           "Problem occurred while reading dependency file.", e);
      -  163  3
               }
      -  164   -
       
      -  165  3
               if (StringUtils.isNotBlank(contents)) {
      -  166  3
                   final Matcher m = PROJECT.matcher(contents);
      -  167  3
                   int count = 0;
      -  168  5
                   while (m.find()) {
      -  169  2
                       count++;
      -  170  4
                       LOGGER.debug(String.format(
      -  171   -
                               "Found project command match with %d groups: %s",
      -  172  2
                               m.groupCount(), m.group(0)));
      -  173  2
                       final String group = m.group(1);
      -  174  2
                       LOGGER.debug("Group 1: " + group);
      -  175  2
                       dependency.getProductEvidence().addEvidence(name, "Project",
      -  176   -
                               group, Confidence.HIGH);
      -  177  2
                   }
      -  178  3
                   LOGGER.debug("Found {} matches.", count);
      -  179  3
                   analyzeSetVersionCommand(dependency, engine, contents);
      -  180   -
               }
      -  181  3
           }
      -  182   -
       
      -  183   -
           /**
      -  184   -
            * Extracts the version information from the contents. If more then one version is found additional dependencies are added to
      -  185   -
            * the dependency list.
      -  186   -
            *
      -  187   -
            * @param dependency the dependency being analyzed
      -  188   -
            * @param engine the dependency-check engine
      -  189   -
            * @param contents the version information
      -  190   -
            */
      -  191   -
           private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) {
      -  192  3
               Dependency currentDep = dependency;
      -  193   -
       
      -  194  3
               final Matcher m = SET_VERSION.matcher(contents);
      -  195  3
               int count = 0;
      -  196  8
               while (m.find()) {
      -  197  5
                   count++;
      -  198  10
                   LOGGER.debug("Found project command match with {} groups: {}",
      -  199  5
                           m.groupCount(), m.group(0));
      -  200  5
                   String product = m.group(1);
      -  201  5
                   final String version = m.group(2);
      -  202  5
                   LOGGER.debug("Group 1: " + product);
      -  203  5
                   LOGGER.debug("Group 2: " + version);
      -  204  5
                   final String aliasPrefix = "ALIASOF_";
      -  205  5
                   if (product.startsWith(aliasPrefix)) {
      -  206  5
                       product = product.replaceFirst(aliasPrefix, "");
      -  207   -
                   }
      -  208  5
                   if (count > 1) {
      -  209   -
                       //TODO - refactor so we do not assign to the parameter (checkstyle)
      -  210  4
                       currentDep = new Dependency(dependency.getActualFile());
      -  211  4
                       currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product));
      -  212  4
                       final String filePath = String.format("%s:%s", dependency.getFilePath(), product);
      -  213  4
                       currentDep.setFilePath(filePath);
      -  214   -
       
      -  215   -
                       byte[] path;
      -  216   -
                       try {
      -  217  4
                           path = filePath.getBytes("UTF-8");
      -  218  0
                       } catch (UnsupportedEncodingException ex) {
      -  219  0
                           path = filePath.getBytes();
      -  220  4
                       }
      -  221  4
                       currentDep.setSha1sum(Checksum.getHex(sha1.digest(path)));
      -  222  4
                       engine.getDependencies().add(currentDep);
      -  223   -
                   }
      -  224  5
                   final String source = currentDep.getDisplayFileName();
      -  225  5
                   currentDep.getProductEvidence().addEvidence(source, "Product",
      -  226   -
                           product, Confidence.MEDIUM);
      -  227  5
                   currentDep.getVersionEvidence().addEvidence(source, "Version",
      -  228   -
                           version, Confidence.MEDIUM);
      -  229  5
               }
      -  230  3
               LOGGER.debug(String.format("Found %d matches.", count));
      -  231  3
           }
      -  232   -
       
      -  233   -
           @Override
      -  234   -
           protected String getAnalyzerEnabledSettingKey() {
      -  235  9
               return Settings.KEYS.ANALYZER_CMAKE_ENABLED;
      -  236  
           }
      -  237   +  134   +
       
      +  135   +
           /**
      +  136   +
            * No-op initializer implementation.
      +  137   +
            *
      +  138   +
            * @throws Exception never thrown
      +  139   +
            */
      +  140   +
           @Override
      +  141   +
           protected void initializeFileTypeAnalyzer() throws Exception {
      +  142   +
               // Nothing to do here.
      +  143  10
           }
      +  144   +
       
      +  145   +
           /**
      +  146   +
            * Analyzes python packages and adds evidence to the dependency.
      +  147   +
            *
      +  148   +
            * @param dependency the dependency being analyzed
      +  149   +
            * @param engine the engine being used to perform the scan
      +  150   +
            * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
      +  151   +
            */
      +  152   +
           @Override
      +  153   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  154   +
                   throws AnalysisException {
      +  155  6
               final File file = dependency.getActualFile();
      +  156  6
               final String parentName = file.getParentFile().getName();
      +  157  6
               final String name = file.getName();
      +  158  6
               dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name));
      +  159   +
               String contents;
      +  160   +
               try {
      +  161  6
                   contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim();
      +  162  0
               } catch (IOException e) {
      +  163  0
                   throw new AnalysisException(
      +  164   +
                           "Problem occurred while reading dependency file.", e);
      +  165  6
               }
      +  166   +
       
      +  167  6
               if (StringUtils.isNotBlank(contents)) {
      +  168  6
                   final Matcher m = PROJECT.matcher(contents);
      +  169  6
                   int count = 0;
      +  170  10
                   while (m.find()) {
      +  171  4
                       count++;
      +  172  8
                       LOGGER.debug(String.format(
      +  173   +
                               "Found project command match with %d groups: %s",
      +  174  4
                               m.groupCount(), m.group(0)));
      +  175  4
                       final String group = m.group(1);
      +  176  4
                       LOGGER.debug("Group 1: " + group);
      +  177  4
                       dependency.getProductEvidence().addEvidence(name, "Project",
      +  178   +
                               group, Confidence.HIGH);
      +  179  4
                   }
      +  180  6
                   LOGGER.debug("Found {} matches.", count);
      +  181  6
                   analyzeSetVersionCommand(dependency, engine, contents);
      +  182   +
               }
      +  183  6
           }
      +  184   +
       
      +  185   +
           /**
      +  186   +
            * Extracts the version information from the contents. If more then one version is found additional dependencies are added to
      +  187   +
            * the dependency list.
      +  188   +
            *
      +  189   +
            * @param dependency the dependency being analyzed
      +  190   +
            * @param engine the dependency-check engine
      +  191   +
            * @param contents the version information
      +  192   +
            */
      +  193   +
           private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) {
      +  194  6
               Dependency currentDep = dependency;
      +  195   +
       
      +  196  6
               final Matcher m = SET_VERSION.matcher(contents);
      +  197  6
               int count = 0;
      +  198  16
               while (m.find()) {
      +  199  10
                   count++;
      +  200  20
                   LOGGER.debug("Found project command match with {} groups: {}",
      +  201  10
                           m.groupCount(), m.group(0));
      +  202  10
                   String product = m.group(1);
      +  203  10
                   final String version = m.group(2);
      +  204  10
                   LOGGER.debug("Group 1: " + product);
      +  205  10
                   LOGGER.debug("Group 2: " + version);
      +  206  10
                   final String aliasPrefix = "ALIASOF_";
      +  207  10
                   if (product.startsWith(aliasPrefix)) {
      +  208  10
                       product = product.replaceFirst(aliasPrefix, "");
      +  209   +
                   }
      +  210  10
                   if (count > 1) {
      +  211   +
                       //TODO - refactor so we do not assign to the parameter (checkstyle)
      +  212  8
                       currentDep = new Dependency(dependency.getActualFile());
      +  213  8
                       currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product));
      +  214  8
                       final String filePath = String.format("%s:%s", dependency.getFilePath(), product);
      +  215  8
                       currentDep.setFilePath(filePath);
      +  216   +
       
      +  217   +
                       byte[] path;
      +  218   +
                       try {
      +  219  8
                           path = filePath.getBytes("UTF-8");
      +  220  0
                       } catch (UnsupportedEncodingException ex) {
      +  221  0
                           path = filePath.getBytes();
      +  222  8
                       }
      +  223  8
                       currentDep.setSha1sum(Checksum.getHex(sha1.digest(path)));
      +  224  8
                       engine.getDependencies().add(currentDep);
      +  225   +
                   }
      +  226  10
                   final String source = currentDep.getDisplayFileName();
      +  227  10
                   currentDep.getProductEvidence().addEvidence(source, "Product",
      +  228   +
                           product, Confidence.MEDIUM);
      +  229  10
                   currentDep.getVersionEvidence().addEvidence(source, "Version",
      +  230   +
                           version, Confidence.MEDIUM);
      +  231  10
               }
      +  232  6
               LOGGER.debug(String.format("Found %d matches.", count));
      +  233  6
           }
      +  234   +
       
      +  235   +
           @Override
      +  236   +
           protected String getAnalyzerEnabledSettingKey() {
      +  237  22
               return Settings.KEYS.ANALYZER_CMAKE_ENABLED;
      +  238   +
           }
      +  239  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CPEAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CPEAnalyzer.html index 08c4d9e11..87e9f5ae9 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CPEAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CPEAnalyzer.html @@ -12,7 +12,7 @@
       
      - + @@ -126,1172 +126,1232 @@ - + - + - + - + + + - - - + - + - + + + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + + - + - + - - - + + - + - + - + - + - - + + + - + - + - - - + + - + - + - + - + - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + - - - - - - - - - - - + + + - - - + + - + - - - + + - + - + - + - + - + - + - + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + - - - - - - - - - - - - + + + + - + - - - - - + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + - + + - - - + + + + + - + - - - + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + - + - - - - - - - - + + + + + - - - + + - - - + + - - - - - + + + - + - + - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - + + + + + + + + + + + + - + - + - - + + - + - + - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + - - - - - + + + + + + + + + - - + + + - - - + + + + + - - + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + - - - - - + + + - - - - + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - + + + + + + - - - - - - + + + + + - + - + - - - + + - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + - - + - + - + - + - + - + - - - - + + + + - + - + - + - + - + - + - + - - - + + + + + - - - - - - - - - - + + + + + - + - + - + - - + + + - + - + - + - + - + - - - + + - - - - - - - - - - - - + + - + - - - + + + + + + + + + + + + + - + - - + + + - + - + - + - + - + - - - + + - - - + + + + + - + - + - + - + - - - - - + + + - + - + - - + + + - + - + - + - + - + - + - - - + + - + - - - - - - + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + - - - + + + - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      CPEAnalyzer
      81%
      189/233
      73%
      98/134
      4.607
      CPEAnalyzer
      83%
      194/232
      76%
      103/134
      4.607
      CPEAnalyzer$IdentifierConfidence
      100%
      4/4
      N/A
      4.607
      CPEAnalyzer$IdentifierMatch
      38%
      15/39
      16%
      4/24
      4.607
       53  
       /**
       54  
        * CPEAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated CPE. It uses
        * CPEAnalyzer is a utility class that takes a project dependency and attempts
       55  
        * the evidence contained within the dependency to search the Lucene index.
        * to discern if there is an associated CPE. It uses the evidence contained
       56  
        *
        * within the dependency to search the Lucene index.
       57  
        * @author Jeremy Long
        *
       58  
        * @author Jeremy Long
       59  
        */
       59  4
       public class CPEAnalyzer implements Analyzer {
       60  
       
       60  12
       public class CPEAnalyzer implements Analyzer {
       61  
           /**
       
       62  
            * The Logger.
           /**
       63  
            * The Logger.
       64  
            */
       64  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class);
       65  
           /**
       65  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class);
       66  
            * The maximum number of query results to return.
           /**
       67  
            */
            * The maximum number of query results to return.
       68  
           static final int MAX_QUERY_RESULTS = 25;
            */
       69  
           /**
           static final int MAX_QUERY_RESULTS = 25;
       70  
            * The weighting boost to give terms when constructing the Lucene query.
           /**
       71  
            */
            * The weighting boost to give terms when constructing the Lucene query.
       72  
           static final String WEIGHTING_BOOST = "^5";
            */
       73  
           /**
           static final String WEIGHTING_BOOST = "^5";
       74  
            * A string representation of a regular expression defining characters utilized within the CPE Names.
           /**
       75  
            */
            * A string representation of a regular expression defining characters
       76  
           static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]";
            * utilized within the CPE Names.
       77  
           /**
            */
       78  
            * A string representation of a regular expression used to remove all but alpha characters.
           static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]";
       79  
            */
           /**
       80  
           static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*";
            * A string representation of a regular expression used to remove all but
       81  
           /**
            * alpha characters.
       82  
            * The additional size to add to a new StringBuilder to account for extra data that will be written into the string.
       83  
            */
       83  
           static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*";
       84  
           static final int STRING_BUILDER_BUFFER = 20;
       85  
           /**
       85  
            * The additional size to add to a new StringBuilder to account for extra
       86  
            * The CPE in memory index.
            * data that will be written into the string.
       87  
            */
       88  
           private CpeMemoryIndex cpe;
           static final int STRING_BUILDER_BUFFER = 20;
       89  
           /**
       90  
            * The CVE Database.
            * The CPE in memory index.
       91  
            */
       92  
           private CveDB cve;
           private CpeMemoryIndex cpe;
       93  
       
           /**
       94  
           /**
            * The CVE Database.
       95  
            * The URL to perform a search of the NVD CVE data at NIST.
            */
       96  
            */
           private CveDB cve;
       97  
           public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s";
       
       98  
       
           /**
       99  
           /**
            * The URL to perform a search of the NVD CVE data at NIST.
       100  
            * Returns the name of this analyzer.
            */
       101  
            *
           public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s";
       102  
            * @return the name of this analyzer.
       
       103  
            */
           /**
       104  
           @Override
            * Returns the name of this analyzer.
       105  
           public String getName() {
       106  4
               return "CPE Analyzer";
            *
       106  
            * @return the name of this analyzer.
       107  
           }
            */
       108  
       
           @Override
       109  
           /**
       110  
            * Returns the analysis phase that this analyzer should run in.
           public String getName() {
       110  32
               return "CPE Analyzer";
       111  
            *
           }
       112  
            * @return the analysis phase that this analyzer should run in.
       
       113  
            */
           /**
       114  
           @Override
            * Returns the analysis phase that this analyzer should run in.
       115  
           public AnalysisPhase getAnalysisPhase() {
       116  3
               return AnalysisPhase.IDENTIFIER_ANALYSIS;
            *
       116  
            * @return the analysis phase that this analyzer should run in.
       117  
           }
            */
       118  
       
           @Override
       119  
           /**
       120  
            * Creates the CPE Lucene Index.
           public AnalysisPhase getAnalysisPhase() {
       120  8
               return AnalysisPhase.IDENTIFIER_ANALYSIS;
       121  
            *
           }
       122  
            * @throws Exception is thrown if there is an issue opening the index.
       
       123  
            */
           /**
       124  
           @Override
            * Creates the CPE Lucene Index.
       125  
           public void initialize() throws Exception {
       126  1
               this.open();
       127  1
           }
            *
       126  
            * @throws Exception is thrown if there is an issue opening the index.
       127  
            */
       128  
       
       129  
           /**
       130  
            * Opens the data source.
       131  
            *
       132  
            * @throws IOException when the Lucene directory to be queried does not exist or is corrupt.
       133  
            * @throws DatabaseException when the database throws an exception. This usually occurs when the database is in use by another
       134  
            * process.
       135  
            */
       136  
           public void open() throws IOException, DatabaseException {
       137  1
               if (!isOpen()) {
       138  1
                   cve = new CveDB();
       139  1
                   cve.open();
       140  1
                   cpe = CpeMemoryIndex.getInstance();
       141  
                   try {
       142  1
                       LOGGER.info("Creating the CPE Index");
       143  1
                       final long creationStart = System.currentTimeMillis();
       144  1
                       cpe.open(cve);
       145  1
                       LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart);
       146  0
                   } catch (IndexException ex) {
       147  0
                       LOGGER.debug("IndexException", ex);
       148  0
                       throw new DatabaseException(ex);
       149  1
                   }
       150  
               }
       151  1
           }
       152  
       
       153  
           /**
       154  
            * Closes the data sources.
       155  
            */
       156  
           @Override
       129  
           public void initialize() throws Exception {
       130  4
               this.open();
       131  4
           }
       132  
       
       133  
           /**
       134  
            * Opens the data source.
       135  
            *
       136  
            * @throws IOException when the Lucene directory to be queried does not
       137  
            * exist or is corrupt.
       138  
            * @throws DatabaseException when the database throws an exception. This
       139  
            * usually occurs when the database is in use by another process.
       140  
            */
       141  
           public void open() throws IOException, DatabaseException {
       142  4
               if (!isOpen()) {
       143  4
                   cve = new CveDB();
       144  4
                   cve.open();
       145  4
                   cpe = CpeMemoryIndex.getInstance();
       146  
                   try {
       147  4
                       LOGGER.info("Creating the CPE Index");
       148  4
                       final long creationStart = System.currentTimeMillis();
       149  4
                       cpe.open(cve);
       150  4
                       LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart);
       151  0
                   } catch (IndexException ex) {
       152  0
                       LOGGER.debug("IndexException", ex);
       153  0
                       throw new DatabaseException(ex);
       154  4
                   }
       155  
               }
       156  4
           }
       157  
           public void close() {
       158  1
               if (cpe != null) {
       159  1
                   cpe.close();
       160  1
                   cpe = null;
       
       158  
           /**
       159  
            * Closes the data sources.
       160  
            */
       161  
           @Override
       162  
           public void close() {
       163  4
               if (cpe != null) {
       164  4
                   cpe.close();
       165  4
                   cpe = null;
       166  
               }
       162  1
               if (cve != null) {
       163  1
                   cve.close();
       164  1
                   cve = null;
       165  
               }
       166  1
           }
       167  
       
       168  
           public boolean isOpen() {
       169  1
               return cpe != null && cpe.isOpen();
       167  4
               if (cve != null) {
       168  4
                   cve.close();
       169  4
                   cve = null;
       170  
           }
       171  
       
               }
       171  4
           }
       172  
           /**
       
       173  
            * Searches the data store of CPE entries, trying to identify the CPE for the given dependency based on the evidence contained
       174  
            * within. The dependency passed in is updated with any identified CPE values.
           public boolean isOpen() {
       174  4
               return cpe != null && cpe.isOpen();
       175  
            *
           }
       176  
            * @param dependency the dependency to search for CPE entries on.
       
       177  
            * @throws CorruptIndexException is thrown when the Lucene index is corrupt.
           /**
       178  
            * @throws IOException is thrown when an IOException occurs.
            * Searches the data store of CPE entries, trying to identify the CPE for
       179  
            * @throws ParseException is thrown when the Lucene query cannot be parsed.
            * the given dependency based on the evidence contained within. The
       180  
            */
            * dependency passed in is updated with any identified CPE values.
       181  
           protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
            *
       182  
            * @param dependency the dependency to search for CPE entries on.
       183  
            * @throws CorruptIndexException is thrown when the Lucene index is corrupt.
       184  
            * @throws IOException is thrown when an IOException occurs.
       185  
            * @throws ParseException is thrown when the Lucene query cannot be parsed.
       186  
            */
       187  
           protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
       188  
               //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit
       183  2
               String vendors = "";
       184  2
               String products = "";
       185  7
               for (Confidence confidence : Confidence.values()) {
       186  6
                   if (dependency.getVendorEvidence().contains(confidence)) {
       187  5
                       vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence);
       188  5
                       LOGGER.debug("vendor search: {}", vendors);
       189  
       189  8
               String vendors = "";
       190  8
               String products = "";
       191  34
               for (Confidence confidence : Confidence.values()) {
       192  28
                   if (dependency.getVendorEvidence().contains(confidence)) {
       193  18
                       vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence);
       194  18
                       LOGGER.debug("vendor search: {}", vendors);
       195  
                   }
       190  6
                   if (dependency.getProductEvidence().contains(confidence)) {
       191  5
                       products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence);
       192  5
                       LOGGER.debug("product search: {}", products);
       193  
                   }
       194  6
                   if (!vendors.isEmpty() && !products.isEmpty()) {
       195  12
                       final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(),
       196  6
                               dependency.getVendorEvidence().getWeighting());
       197  6
                       if (entries == null) {
       198  0
                           continue;
       196  28
                   if (dependency.getProductEvidence().contains(confidence)) {
       197  16
                       products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence);
       198  16
                       LOGGER.debug("product search: {}", products);
       199  
                       }
       200  6
                       boolean identifierAdded = false;
       201  6
                       for (IndexEntry e : entries) {
       202  90
                           LOGGER.debug("Verifying entry: {}", e);
       203  90
                           if (verifyEntry(e, dependency)) {
       204  3
                               final String vendor = e.getVendor();
       205  3
                               final String product = e.getProduct();
       206  3
                               LOGGER.debug("identified vendor/product: {}/{}", vendor, product);
       207  3
                               identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence);
       208  
                           }
       209  90
                       }
       210  6
                       if (identifierAdded) {
       211  1
                           break;
       212  
                       }
       213  
                   }
       200  28
                   if (!vendors.isEmpty() && !products.isEmpty()) {
       201  44
                       final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(),
       202  22
                               dependency.getProductEvidence().getWeighting());
       203  22
                       if (entries == null) {
       204  0
                           continue;
       205  
                       }
       206  22
                       boolean identifierAdded = false;
       207  22
                       for (IndexEntry e : entries) {
       208  90
                           LOGGER.debug("Verifying entry: {}", e);
       209  90
                           if (verifyEntry(e, dependency)) {
       210  6
                               final String vendor = e.getVendor();
       211  6
                               final String product = e.getProduct();
       212  6
                               LOGGER.debug("identified vendor/product: {}/{}", vendor, product);
       213  6
                               identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence);
       214  
               }
       215  2
           }
       216  
       
       217  
           /**
       218  
            * Returns the text created by concatenating the text and the values from the EvidenceCollection (filtered for a specific
       219  
            * confidence). This attempts to prevent duplicate terms from being added.<br/<br/> Note, if the evidence is longer then 200
       220  
            * characters it will be truncated.
       221  
            *
       222  
            * @param text the base text.
       223  
            * @param ec an EvidenceCollection
       224  
            * @param confidenceFilter a Confidence level to filter the evidence by.
       225  
            * @return the new evidence text
       226  
            */
       227  
           private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) {
       228  10
               final String txt = (text == null) ? "" : text;
       229  10
               final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size()));
       230  10
               sb.append(' ').append(txt).append(' ');
       231  10
               for (Evidence e : ec.iterator(confidenceFilter)) {
       232  26
                   String value = e.getValue();
       233  
       
       234  
                   //hack to get around the fact that lucene does a really good job of recognizing domains and not
       235  
                   // splitting them. TODO - put together a better lucene analyzer specific to the domain.
       236  26
                   if (value.startsWith("http://")) {
       237  2
                       value = value.substring(7).replaceAll("\\.", " ");
       238  
                   }
       239  26
                   if (value.startsWith("https://")) {
       240  0
                       value = value.substring(8).replaceAll("\\.", " ");
       241  
                   }
       242  26
                   if (sb.indexOf(" " + value + " ") < 0) {
       243  26
                       sb.append(value).append(' ');
       244  
                   }
       245  26
               }
       246  10
               return sb.toString().trim();
       247  
           }
       248  
       
       249  
           /**
       250  
            * <p>
       251  
            * Searches the Lucene CPE index to identify possible CPE entries associated with the supplied vendor, product, and
       252  
            * version.</p>
       253  
            *
       254  
            * <p>
       255  
            * If either the vendorWeightings or productWeightings lists have been populated this data is used to add weighting factors to
       256  
            * the search.</p>
       257  
            *
       258  
            * @param vendor the text used to search the vendor field
       259  
            * @param product the text used to search the product field
       260  
            * @param vendorWeightings a list of strings to use to add weighting factors to the vendor field
       261  
            * @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search
       262  
            * @return a list of possible CPE values
       263  
            */
       264  
           protected List<IndexEntry> searchCPE(String vendor, String product,
       265  
                   Set<String> vendorWeightings, Set<String> productWeightings) {
       266  
       
       267  6
               final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
       268  
       
       269  6
               final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
       270  6
               if (searchString == null) {
       271  0
                   return ret;
       272  
               }
       273  
               try {
       274  6
                   final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
       275  156
                   for (ScoreDoc d : docs.scoreDocs) {
       276  150
                       if (d.score >= 0.08) {
       277  90
                           final Document doc = cpe.getDocument(d.doc);
       278  90
                           final IndexEntry entry = new IndexEntry();
       279  90
                           entry.setVendor(doc.get(Fields.VENDOR));
       280  90
                           entry.setProduct(doc.get(Fields.PRODUCT));
       281  90
                           entry.setSearchScore(d.score);
       282  90
                           if (!ret.contains(entry)) {
       283  90
                               ret.add(entry);
       284  
                           }
       285  
       215  90
                       }
       216  22
                       if (identifierAdded) {
       217  2
                           break;
       218  
                       }
       286  
       219  
                   }
       287  6
                   return ret;
       288  0
               } catch (ParseException ex) {
       289  0
                   LOGGER.warn("An error occurred querying the CPE data. See the log for more details.");
       290  0
                   LOGGER.info("Unable to parse: {}", searchString, ex);
       291  0
               } catch (IOException ex) {
       292  0
                   LOGGER.warn("An error occurred reading CPE data. See the log for more details.");
       293  0
                   LOGGER.info("IO Error with search string: {}", searchString, ex);
       294  0
               }
       295  0
               return null;
       296  
           }
       297  
       220  
               }
       221  8
           }
       222  
       
       298  
       223  
           /**
       299  
            * <p>
       300  
            * Builds a Lucene search string by properly escaping data and constructing a valid search query.</p>
       301  
       224  
            * Returns the text created by concatenating the text and the values from
       225  
            * the EvidenceCollection (filtered for a specific confidence). This
       226  
            * attempts to prevent duplicate terms from being added.<br/<br/> Note, if
       227  
            * the evidence is longer then 200 characters it will be truncated.
       228  
            *
       302  
       229  
            * @param text the base text.
       230  
            * @param ec an EvidenceCollection
       231  
            * @param confidenceFilter a Confidence level to filter the evidence by.
       232  
            * @return the new evidence text
       233  
            */
       234  
           private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) {
       235  34
               final String txt = (text == null) ? "" : text;
       236  34
               final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size()));
       237  34
               sb.append(' ').append(txt).append(' ');
       238  34
               for (Evidence e : ec.iterator(confidenceFilter)) {
       239  74
                   String value = e.getValue();
       240  
       
       241  
                   //hack to get around the fact that lucene does a really good job of recognizing domains and not
       242  
                   // splitting them. TODO - put together a better lucene analyzer specific to the domain.
       243  74
                   if (value.startsWith("http://")) {
       244  4
                       value = value.substring(7).replaceAll("\\.", " ");
       245  
                   }
       246  74
                   if (value.startsWith("https://")) {
       247  2
                       value = value.substring(8).replaceAll("\\.", " ");
       248  
                   }
       249  74
                   if (sb.indexOf(" " + value + " ") < 0) {
       250  74
                       sb.append(value).append(' ');
       251  
                   }
       252  74
               }
       253  34
               return sb.toString().trim();
       254  
           }
       255  
       
       256  
           /**
       257  
            * <p>
       303  
            * If either the possibleVendor or possibleProducts lists have been populated this data is used to add weighting factors to
       304  
            * the search string generated.</p>
       258  
            * Searches the Lucene CPE index to identify possible CPE entries associated
       259  
            * with the supplied vendor, product, and version.</p>
       260  
            *
       261  
            * <p>
       262  
            * If either the vendorWeightings or productWeightings lists have been
       263  
            * populated this data is used to add weighting factors to the search.</p>
       264  
            *
       265  
            * @param vendor the text used to search the vendor field
       266  
            * @param product the text used to search the product field
       267  
            * @param vendorWeightings a list of strings to use to add weighting factors
       268  
            * to the vendor field
       269  
            * @param productWeightings Adds a list of strings that will be used to add
       270  
            * weighting factors to the product search
       271  
            * @return a list of possible CPE values
       272  
            */
       273  
           protected List<IndexEntry> searchCPE(String vendor, String product,
       274  
                   Set<String> vendorWeightings, Set<String> productWeightings) {
       275  
       
       276  22
               final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
       277  
       
       278  22
               final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
       279  22
               if (searchString == null) {
       280  0
                   return ret;
       281  
               }
       282  
               try {
       283  22
                   final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
       284  372
                   for (ScoreDoc d : docs.scoreDocs) {
       285  350
                       if (d.score >= 0.08) {
       286  90
                           final Document doc = cpe.getDocument(d.doc);
       287  90
                           final IndexEntry entry = new IndexEntry();
       288  90
                           entry.setVendor(doc.get(Fields.VENDOR));
       289  90
                           entry.setProduct(doc.get(Fields.PRODUCT));
       290  90
                           entry.setSearchScore(d.score);
       291  90
                           if (!ret.contains(entry)) {
       292  90
                               ret.add(entry);
       293  
                           }
       294  
                       }
       295  
                   }
       296  22
                   return ret;
       297  0
               } catch (ParseException ex) {
       298  0
                   LOGGER.warn("An error occurred querying the CPE data. See the log for more details.");
       299  0
                   LOGGER.info("Unable to parse: {}", searchString, ex);
       300  0
               } catch (IOException ex) {
       301  0
                   LOGGER.warn("An error occurred reading CPE data. See the log for more details.");
       302  0
                   LOGGER.info("IO Error with search string: {}", searchString, ex);
       303  0
               }
       304  0
               return null;
       305  
            *
       306  
            * @param vendor text to search the vendor field
       307  
            * @param product text to search the product field
       308  
            * @param vendorWeighting a list of strings to apply to the vendor to boost the terms weight
       309  
            * @param productWeightings a list of strings to apply to the product to boost the terms weight
       310  
            * @return the Lucene query
       311  
            */
       312  
           protected String buildSearch(String vendor, String product,
       313  
                   Set<String> vendorWeighting, Set<String> productWeightings) {
       314  6
               final String v = vendor; //.replaceAll("[^\\w\\d]", " ");
       315  6
               final String p = product; //.replaceAll("[^\\w\\d]", " ");
       316  6
               final StringBuilder sb = new StringBuilder(v.length() + p.length()
       317  6
                       + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER);
       318  
       
       319  6
               if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) {
       320  0
                   return null;
       321  
               }
       322  6
               sb.append(" AND ");
       323  6
               if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) {
       324  0
                   return null;
       325  
               }
       326  6
               return sb.toString();
       327  
           }
       328  
       306  
       
       329  
       307  
           /**
       330  
            * This method constructs a Lucene query for a given field. The searchText is split into separate words and if the word is
       331  
            * within the list of weighted words then an additional weighting is applied to the term as it is appended into the query.
       332  
       308  
            * <p>
       309  
            * Builds a Lucene search string by properly escaping data and constructing
       310  
            * a valid search query.</p>
       311  
            *
       333  
            * @param sb a StringBuilder that the query text will be appended to.
       334  
            * @param field the field within the Lucene index that the query is searching.
       335  
            * @param searchText text used to construct the query.
       336  
            * @param weightedText a list of terms that will be considered higher importance when searching.
       337  
            * @return if the append was successful.
       338  
       312  
            * <p>
       313  
            * If either the possibleVendor or possibleProducts lists have been
       314  
            * populated this data is used to add weighting factors to the search string
       315  
            * generated.</p>
       316  
            *
       317  
            * @param vendor text to search the vendor field
       318  
            * @param product text to search the product field
       319  
            * @param vendorWeighting a list of strings to apply to the vendor to boost
       320  
            * the terms weight
       321  
            * @param productWeightings a list of strings to apply to the product to
       322  
            * boost the terms weight
       323  
            * @return the Lucene query
       324  
            */
       339  
           private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) {
       340  12
               sb.append(' ').append(field).append(":( ");
       325  
           protected String buildSearch(String vendor, String product,
       326  
                   Set<String> vendorWeighting, Set<String> productWeightings) {
       327  22
               final String v = vendor; //.replaceAll("[^\\w\\d]", " ");
       328  22
               final String p = product; //.replaceAll("[^\\w\\d]", " ");
       329  22
               final StringBuilder sb = new StringBuilder(v.length() + p.length()
       330  22
                       + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER);
       331  
       
       332  22
               if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) {
       333  0
                   return null;
       334  
               }
       335  22
               sb.append(" AND ");
       336  22
               if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) {
       337  0
                   return null;
       338  
               }
       339  22
               return sb.toString();
       340  
           }
       341  
       
       342  12
               final String cleanText = cleanseText(searchText);
       342  
           /**
       343  
       
       344  12
               if (cleanText.isEmpty()) {
       345  0
                   return false;
            * This method constructs a Lucene query for a given field. The searchText
       344  
            * is split into separate words and if the word is within the list of
       345  
            * weighted words then an additional weighting is applied to the term as it
       346  
               }
            * is appended into the query.
       347  
       
       348  12
               if (weightedText == null || weightedText.isEmpty()) {
       349  0
                   LuceneUtils.appendEscapedLuceneQuery(sb, cleanText);
            *
       348  
            * @param sb a StringBuilder that the query text will be appended to.
       349  
            * @param field the field within the Lucene index that the query is
       350  
               } else {
       351  12
                   final StringTokenizer tokens = new StringTokenizer(cleanText);
       352  115
                   while (tokens.hasMoreElements()) {
       353  103
                       final String word = tokens.nextToken();
       354  103
                       StringBuilder temp = null;
       355  103
                       for (String weighted : weightedText) {
       356  242
                           final String weightedStr = cleanseText(weighted);
       357  242
                           if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
       358  6
                               temp = new StringBuilder(word.length() + 2);
       359  6
                               LuceneUtils.appendEscapedLuceneQuery(temp, word);
       360  6
                               temp.append(WEIGHTING_BOOST);
       361  6
                               if (!word.equalsIgnoreCase(weightedStr)) {
       362  0
                                   temp.append(' ');
       363  0
                                   LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr);
       364  0
                                   temp.append(WEIGHTING_BOOST);
       365  
                               }
       366  
                               break;
            * searching.
       351  
            * @param searchText text used to construct the query.
       352  
            * @param weightedText a list of terms that will be considered higher
       353  
            * importance when searching.
       354  
            * @return if the append was successful.
       355  
            */
       356  
           private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) {
       357  44
               sb.append(' ').append(field).append(":( ");
       358  
       
       359  44
               final String cleanText = cleanseText(searchText);
       360  
       
       361  44
               if (cleanText.isEmpty()) {
       362  0
                   return false;
       363  
               }
       364  
       
       365  44
               if (weightedText == null || weightedText.isEmpty()) {
       366  28
                   LuceneUtils.appendEscapedLuceneQuery(sb, cleanText);
       367  
                           }
       368  236
                       }
       369  103
                       sb.append(' ');
       370  103
                       if (temp == null) {
       371  97
                           LuceneUtils.appendEscapedLuceneQuery(sb, word);
       372  
                       } else {
       373  6
                           sb.append(temp);
       374  
                       }
       375  103
                   }
       376  
               }
       377  12
               sb.append(" ) ");
       378  12
               return true;
       379  
           }
       380  
       
       381  
           /**
               } else {
       368  16
                   final StringTokenizer tokens = new StringTokenizer(cleanText);
       369  214
                   while (tokens.hasMoreElements()) {
       370  198
                       final String word = tokens.nextToken();
       371  198
                       StringBuilder temp = null;
       372  198
                       for (String weighted : weightedText) {
       373  460
                           final String weightedStr = cleanseText(weighted);
       374  460
                           if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
       375  14
                               temp = new StringBuilder(word.length() + 2);
       376  14
                               LuceneUtils.appendEscapedLuceneQuery(temp, word);
       377  14
                               temp.append(WEIGHTING_BOOST);
       378  14
                               if (!word.equalsIgnoreCase(weightedStr)) {
       379  0
                                   temp.append(' ');
       380  0
                                   LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr);
       381  0
                                   temp.append(WEIGHTING_BOOST);
       382  
            * Removes characters from the input text that are not used within the CPE index.
                               }
       383  
            *
                               break;
       384  
            * @param text is the text to remove the characters from.
       385  
            * @return the text having removed some characters.
       386  
            */
       387  
           private String cleanseText(String text) {
       388  254
               return text.replaceAll(CLEANSE_CHARACTER_RX, " ");
                           }
       385  446
                       }
       386  198
                       sb.append(' ');
       387  198
                       if (temp == null) {
       388  184
                           LuceneUtils.appendEscapedLuceneQuery(sb, word);
       389  
           }
       390  
       
                       } else {
       390  14
                           sb.append(temp);
       391  
           /**
       392  
            * Compares two strings after lower casing them and removing the non-alpha characters.
                       }
       392  198
                   }
       393  
            *
       394  
            * @param l string one to compare.
       395  
            * @param r string two to compare.
               }
       394  44
               sb.append(" ) ");
       395  44
               return true;
       396  
            * @return whether or not the two strings are similar.
           }
       397  
            */
       
       398  
           private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) {
       399  242
               if (l == null || r == null) {
       400  0
                   return false;
           /**
       399  
            * Removes characters from the input text that are not used within the CPE
       400  
            * index.
       401  
               }
       402  
       
       403  242
               final String left = l.replaceAll(CLEANSE_NONALPHA_RX, "");
       404  242
               final String right = r.replaceAll(CLEANSE_NONALPHA_RX, "");
       405  242
               return left.equalsIgnoreCase(right);
       406  
           }
       407  
       
       408  
           /**
       409  
            * Ensures that the CPE Identified matches the dependency. This validates that the product, vendor, and version information
       410  
            * for the CPE are contained within the dependencies evidence.
       411  
            *
       412  
            * @param entry a CPE entry.
       413  
            * @param dependency the dependency that the CPE entries could be for.
       414  
            * @return whether or not the entry is valid.
       415  
       402  
            * @param text is the text to remove the characters from.
       403  
            * @return the text having removed some characters.
       404  
            */
       416  
           private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) {
       417  90
               boolean isValid = false;
       418  
       
       419  
               //TODO - does this nullify some of the fuzzy matching that happens in the lucene search?
       420  
               // for instance CPE some-component and in the evidence we have SomeComponent.
       421  90
               if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
       422  4
                       && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) {
       423  
                   //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
       424  3
                   isValid = true;
       425  
               }
       426  90
               return isValid;
       427  
       405  
           private String cleanseText(String text) {
       406  504
               return text.replaceAll(CLEANSE_CHARACTER_RX, " ");
       407  
           }
       428  
       408  
       
       429  
       409  
           /**
       410  
            * Compares two strings after lower casing them and removing the non-alpha
       411  
            * characters.
       412  
            *
       413  
            * @param l string one to compare.
       414  
            * @param r string two to compare.
       415  
            * @return whether or not the two strings are similar.
       416  
            */
       417  
           private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) {
       418  460
               if (l == null || r == null) {
       419  0
                   return false;
       420  
               }
       421  
       
       422  460
               final String left = l.replaceAll(CLEANSE_NONALPHA_RX, "");
       423  460
               final String right = r.replaceAll(CLEANSE_NONALPHA_RX, "");
       424  460
               return left.equalsIgnoreCase(right);
       425  
           }
       426  
       
       427  
           /**
       428  
            * Ensures that the CPE Identified matches the dependency. This validates
       429  
            * that the product, vendor, and version information for the CPE are
       430  
            * Used to determine if the EvidenceCollection contains a specific string.
            * contained within the dependencies evidence.
       431  
            *
       432  
            * @param ec an EvidenceCollection
            * @param entry a CPE entry.
       433  
            * @param text the text to search for
            * @param dependency the dependency that the CPE entries could be for.
       434  
            * @return whether or not the EvidenceCollection contains the string
            * @return whether or not the entry is valid.
       435  
            */
       436  
           private boolean collectionContainsString(EvidenceCollection ec, String text) {
       437  
               //TODO - likely need to change the split... not sure if this will work for CPE with special chars
       438  94
               if (text == null) {
       439  0
                   return false;
       440  
               }
       441  94
               final String[] words = text.split("[\\s_-]");
       442  94
               final List<String> list = new ArrayList<String>();
       443  94
               String tempWord = null;
       444  245
               for (String word : words) {
       445  
                   /*
       446  
                    single letter words should be concatenated with the next word.
       447  
                    so { "m", "core", "sample" } -> { "mcore", "sample" }
       448  
                    */
       449  151
                   if (tempWord != null) {
       450  6
                       list.add(tempWord + word);
       451  6
                       tempWord = null;
       452  145
                   } else if (word.length() <= 2) {
       453  6
                       tempWord = word;
       454  
                   } else {
       455  139
                       list.add(word);
       456  
                   }
       457  
               }
       458  94
               if (tempWord != null) {
       459  0
                   if (!list.isEmpty()) {
       460  0
                       final String tmp = list.get(list.size() - 1) + tempWord;
       461  0
                       list.add(tmp);
       462  0
                   } else {
       463  0
                       list.add(tempWord);
       464  
                   }
       465  
               }
       466  94
               if (list.isEmpty()) {
       467  0
                   return false;
       468  
               }
       469  94
               boolean contains = true;
       470  94
               for (String word : list) {
       471  145
                   contains &= ec.containsUsedString(word);
       472  145
               }
       473  94
               return contains;
       474  
           }
       475  
           private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) {
       437  90
               boolean isValid = false;
       438  
       
       476  
       439  
               //TODO - does this nullify some of the fuzzy matching that happens in the lucene search?
       440  
               // for instance CPE some-component and in the evidence we have SomeComponent.
       441  90
               if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
       442  8
                       && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) {
       443  
                   //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
       444  6
                   isValid = true;
       445  
               }
       446  90
               return isValid;
       447  
           }
       448  
       
       449  
           /**
       477  
            * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency.
       478  
       450  
            * Used to determine if the EvidenceCollection contains a specific string.
       451  
            *
       479  
            * @param dependency The Dependency to analyze.
       480  
            * @param engine The analysis engine
       481  
            * @throws AnalysisException is thrown if there is an issue analyzing the dependency.
       482  
       452  
            * @param ec an EvidenceCollection
       453  
            * @param text the text to search for
       454  
            * @return whether or not the EvidenceCollection contains the string
       455  
            */
       483  
           @Override
       456  
           private boolean collectionContainsString(EvidenceCollection ec, String text) {
       457  
               //TODO - likely need to change the split... not sure if this will work for CPE with special chars
       458  98
               if (text == null) {
       459  0
                   return false;
       460  
               }
       461  98
               final String[] words = text.split("[\\s_-]");
       462  98
               final List<String> list = new ArrayList<String>();
       463  98
               String tempWord = null;
       464  286
               for (String word : words) {
       465  
                   /*
       466  
                    single letter words should be concatenated with the next word.
       467  
                    so { "m", "core", "sample" } -> { "mcore", "sample" }
       468  
                    */
       469  188
                   if (tempWord != null) {
       470  6
                       list.add(tempWord + word);
       471  6
                       tempWord = null;
       472  182
                   } else if (word.length() <= 2) {
       473  8
                       tempWord = word;
       474  
                   } else {
       475  174
                       list.add(word);
       476  
                   }
       477  
               }
       478  98
               if (tempWord != null) {
       479  2
                   if (!list.isEmpty()) {
       480  2
                       final String tmp = list.get(list.size() - 1) + tempWord;
       481  2
                       list.add(tmp);
       482  2
                   } else {
       483  0
                       list.add(tempWord);
       484  
           public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException {
                   }
       485  
               try {
       486  2
                   determineCPE(dependency);
       487  0
               } catch (CorruptIndexException ex) {
       488  0
                   throw new AnalysisException("CPE Index is corrupt.", ex);
       489  0
               } catch (IOException ex) {
       490  0
                   throw new AnalysisException("Failure opening the CPE Index.", ex);
       491  0
               } catch (ParseException ex) {
       492  0
                   throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex);
       493  2
               }
       494  2
           }
               }
       486  98
               if (list.isEmpty()) {
       487  0
                   return false;
       488  
               }
       489  98
               boolean contains = true;
       490  98
               for (String word : list) {
       491  182
                   contains &= ec.containsUsedString(word);
       492  182
               }
       493  98
               return contains;
       494  
           }
       495  
       
       496  
           /**
       497  
            * Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then validated to find
            * Analyzes a dependency and attempts to determine if there are any CPE
       498  
            * only CPEs that are valid for the given dependency. It is possible that the CPE identified is a best effort "guess" based on
            * identifiers for this dependency.
       499  
            * the vendor, product, and version information.
       500  
            *
       500  
            * @param dependency The Dependency to analyze.
       501  
            * @param dependency the Dependency being analyzed
            * @param engine The analysis engine
       502  
            * @param vendor the vendor for the CPE being analyzed
            * @throws AnalysisException is thrown if there is an issue analyzing the
       503  
            * @param product the product for the CPE being analyzed
            * dependency.
       504  
            * @param currentConfidence the current confidence being used during analysis
       505  
            * @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code>
       506  
            * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
       507  
            */
       508  
           protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
       509  
                   Confidence currentConfidence) throws UnsupportedEncodingException {
       510  3
               final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
       511  3
               DependencyVersion bestGuess = new DependencyVersion("-");
       512  3
               Confidence bestGuessConf = null;
       513  3
               boolean hasBroadMatch = false;
       514  3
               final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
       515  15
               for (Confidence conf : Confidence.values()) {
       516  
       //            if (conf.compareTo(currentConfidence) > 0) {
       505  
           @Override
       506  
           public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException {
       507  
               try {
       508  8
                   determineCPE(dependency);
       509  0
               } catch (CorruptIndexException ex) {
       510  0
                   throw new AnalysisException("CPE Index is corrupt.", ex);
       511  0
               } catch (IOException ex) {
       512  0
                   throw new AnalysisException("Failure opening the CPE Index.", ex);
       513  0
               } catch (ParseException ex) {
       514  0
                   throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex);
       515  8
               }
       516  8
           }
       517  
       //                break;
       
       518  
       //            }
       519  12
                   for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
       520  12
                       final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
       521  12
                       if (evVer == null) {
       522  0
                           continue;
           /**
       519  
            * Retrieves a list of CPE values from the CveDB based on the vendor and
       520  
            * product passed in. The list is then validated to find only CPEs that are
       521  
            * valid for the given dependency. It is possible that the CPE identified is
       522  
            * a best effort "guess" based on the vendor, product, and version
       523  
                       }
       524  12
                       for (VulnerableSoftware vs : cpes) {
            * information.
       524  
            *
       525  
                           DependencyVersion dbVer;
       526  436
                           if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) {
       527  128
                               dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate());
            * @param dependency the Dependency being analyzed
       526  
            * @param vendor the vendor for the CPE being analyzed
       527  
            * @param product the product for the CPE being analyzed
       528  
                           } else {
       529  308
                               dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
            * @param currentConfidence the current confidence being used during
       529  
            * analysis
       530  
                           }
       531  436
                           if (dbVer == null) { //special case, no version specified - everything is vulnerable
       532  0
                               hasBroadMatch = true;
       533  0
                               final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
       534  0
                               final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf);
       535  0
                               collected.add(match);
       536  0
                           } else if (evVer.equals(dbVer)) { //yeah! exact match
       537  8
                               final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
       538  8
                               final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
       539  8
                               collected.add(match);
       540  8
                           } else {
            * @return <code>true</code> if an identifier was added to the dependency;
       531  
            * otherwise <code>false</code>
       532  
            * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
       533  
            */
       534  
           protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
       535  
                   Confidence currentConfidence) throws UnsupportedEncodingException {
       536  6
               final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
       537  6
               DependencyVersion bestGuess = new DependencyVersion("-");
       538  6
               Confidence bestGuessConf = null;
       539  6
               boolean hasBroadMatch = false;
       540  6
               final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
       541  
                               //TODO the following isn't quite right is it? need to think about this guessing game a bit more.
       542  428
                               if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size()
       543  420
                                       && evVer.matchesAtLeastThreeLevels(dbVer)) {
       544  64
                                   if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
       545  2
                                       if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) {
       546  2
                                           bestGuess = dbVer;
       547  2
                                           bestGuessConf = conf;
       548  
                                       }
       549  
                                   }
       
       542  
               //TODO the following algorithm incorrectly identifies things as a lower version
       543  
               // if there lower confidence evidence when the current (highest) version number 
       544  
               // is newer then anything in the NVD.
       545  30
               for (Confidence conf : Confidence.values()) {
       546  24
                   for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
       547  24
                       final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
       548  24
                       if (evVer == null) {
       549  0
                           continue;
       550  
                               }
       551  
                           }
       552  436
                       }
       553  12
                       if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
       554  1
                           if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
       555  1
                               bestGuess = evVer;
       556  1
                               bestGuessConf = conf;
                       }
       551  24
                       for (VulnerableSoftware vs : cpes) {
       552  
                           DependencyVersion dbVer;
       553  872
                           if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) {
       554  256
                               dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate());
       555  
                           } else {
       556  616
                               dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
       557  
                           }
       558  
                       }
       559  12
                   }
       560  
               }
       561  3
               final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
       562  3
               String url = null;
       563  3
               if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess.
       564  0
                   final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product);
       565  0
                   url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8"));
       566  
               }
       567  3
               if (bestGuessConf == null) {
       568  0
                   bestGuessConf = Confidence.LOW;
       569  
               }
       570  3
               final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
       571  3
               collected.add(match);
       572  
       
       573  3
               Collections.sort(collected);
       574  3
               final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
       575  3
               final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
       576  3
               boolean identifierAdded = false;
       577  3
               for (IdentifierMatch m : collected) {
       578  11
                   if (bestIdentifierQuality.equals(m.getConfidence())
       579  9
                           && bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
       580  3
                       final Identifier i = m.getIdentifier();
       581  3
                       if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) {
       582  1
                           i.setConfidence(Confidence.LOW);
       558  872
                           if (dbVer == null) { //special case, no version specified - everything is vulnerable
       559  0
                               hasBroadMatch = true;
       560  0
                               final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
       561  0
                               final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf);
       562  0
                               collected.add(match);
       563  0
                           } else if (evVer.equals(dbVer)) { //yeah! exact match
       564  16
                               final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
       565  16
                               final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
       566  16
                               collected.add(match);
       567  16
                           } else //TODO the following isn't quite right is it? need to think about this guessing game a bit more.
       568  856
                           if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size()
       569  840
                                   && evVer.matchesAtLeastThreeLevels(dbVer)) {
       570  128
                               if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
       571  4
                                   if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) {
       572  4
                                       bestGuess = dbVer;
       573  4
                                       bestGuessConf = conf;
       574  
                                   }
       575  
                               }
       576  
                           }
       577  872
                       }
       578  24
                       if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
       579  2
                           if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
       580  2
                               bestGuess = evVer;
       581  2
                               bestGuessConf = conf;
       582  
                           }
       583  
                       } else {
       584  2
                           i.setConfidence(bestEvidenceQuality);
       585  
                       }
       586  3
                       dependency.addIdentifier(i);
       587  3
                       identifierAdded = true;
       588  
                   }
       589  11
               }
       590  3
               return identifierAdded;
       584  24
                   }
       585  
               }
       586  6
               final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
       587  6
               String url = null;
       588  6
               if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess.
       589  0
                   final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product);
       590  0
                   url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8"));
       591  
           }
       592  
       
       593  
           /**
               }
       592  6
               if (bestGuessConf == null) {
       593  0
                   bestGuessConf = Confidence.LOW;
       594  
            * The confidence whether the identifier is an exact match, or a best guess.
       595  
            */
       596  4
           private enum IdentifierConfidence {
               }
       595  6
               final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
       596  6
               collected.add(match);
       597  
       
       598  
               /**
       599  
                * An exact match for the CPE.
       600  
                */
       601  1
               EXACT_MATCH,
       602  
               /**
       603  
                * A best guess for the CPE.
       604  
                */
       605  1
               BEST_GUESS,
       606  
               /**
       607  
                * The entire vendor/product group must be added (without a guess at version) because there is a CVE with a VS that only
       598  6
               Collections.sort(collected);
       599  6
               final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
       600  6
               final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
       601  6
               boolean identifierAdded = false;
       602  6
               for (IdentifierMatch m : collected) {
       603  22
                   if (bestIdentifierQuality.equals(m.getConfidence())
       604  18
                           && bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
       605  6
                       final Identifier i = m.getIdentifier();
       606  6
                       if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) {
       607  2
                           i.setConfidence(Confidence.LOW);
       608  
                * specifies vendor/product.
       609  
                */
       610  1
               BROAD_MATCH
       611  
           }
       612  
       
                       } else {
       609  4
                           i.setConfidence(bestEvidenceQuality);
       610  
                       }
       611  6
                       dependency.addIdentifier(i);
       612  6
                       identifierAdded = true;
       613  
           /**
       614  
            * A simple object to hold an identifier and carry information about the confidence in the identifier.
       615  
            */
       616  4
           private static class IdentifierMatch implements Comparable<IdentifierMatch> {
                   }
       614  22
               }
       615  6
               return identifierAdded;
       616  
           }
       617  
       
       618  
               /**
           /**
       619  
                * Constructs an IdentifierMatch.
            * The confidence whether the identifier is an exact match, or a best guess.
       620  
                *
       621  
                * @param type the type of identifier (such as CPE)
            */
       621  8
           private enum IdentifierConfidence {
       622  
                * @param value the value of the identifier
       
       623  
                * @param url the URL of the identifier
       624  
                * @param identifierConfidence the confidence in the identifier: best guess or exact match
       625  
                * @param evidenceConfidence the confidence of the evidence used to find the identifier
       626  
                */
       627  11
               IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) {
       628  11
                   this.identifier = new Identifier(type, value, url);
       629  11
                   this.confidence = identifierConfidence;
       630  11
                   this.evidenceConfidence = evidenceConfidence;
       631  11
               }
       632  
               //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier">
       633  
               /**
       624  
                * An exact match for the CPE.
       625  
                */
       626  2
               EXACT_MATCH,
       627  
               /**
       628  
                * A best guess for the CPE.
       629  
                */
       630  2
               BEST_GUESS,
       631  
               /**
       632  
                * The entire vendor/product group must be added (without a guess at
       633  
                * version) because there is a CVE with a VS that only specifies
       634  
                * The confidence in the evidence used to identify this match.
                * vendor/product.
       635  
                */
       636  
               private Confidence evidenceConfidence;
       636  2
               BROAD_MATCH
       637  
       
           }
       638  
               /**
       
       639  
                * Get the value of evidenceConfidence
           /**
       640  
                *
            * A simple object to hold an identifier and carry information about the
       641  
                * @return the value of evidenceConfidence
            * confidence in the identifier.
       642  
                */
       643  
               public Confidence getEvidenceConfidence() {
       644  12
                   return evidenceConfidence;
            */
       643  16
           private static class IdentifierMatch implements Comparable<IdentifierMatch> {
       644  
       
       645  
               }
               /**
       646  
       
                * Constructs an IdentifierMatch.
       647  
               /**
                *
       648  
                * Set the value of evidenceConfidence
                * @param type the type of identifier (such as CPE)
       649  
                *
                * @param value the value of the identifier
       650  
                * @param evidenceConfidence new value of evidenceConfidence
                * @param url the URL of the identifier
       651  
                */
                * @param identifierConfidence the confidence in the identifier: best
       652  
               public void setEvidenceConfidence(Confidence evidenceConfidence) {
       653  0
                   this.evidenceConfidence = evidenceConfidence;
       654  0
               }
                * guess or exact match
       653  
                * @param evidenceConfidence the confidence of the evidence used to find
       654  
                * the identifier
       655  
               /**
       656  
                * The confidence whether this is an exact match, or a best guess.
       657  
                */
       658  
               private IdentifierConfidence confidence;
       659  
       
       660  
               /**
       656  22
               IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) {
       657  22
                   this.identifier = new Identifier(type, value, url);
       658  22
                   this.confidence = identifierConfidence;
       659  22
                   this.evidenceConfidence = evidenceConfidence;
       660  22
               }
       661  
                * Get the value of confidence.
               //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier">
       662  
                *
               /**
       663  
                * @return the value of confidence
                * The confidence in the evidence used to identify this match.
       664  
                */
       665  
               public IdentifierConfidence getConfidence() {
       666  14
                   return confidence;
               private Confidence evidenceConfidence;
       666  
       
       667  
               }
               /**
       668  
       
                * Get the value of evidenceConfidence
       669  
               /**
                *
       670  
                * Set the value of confidence.
                * @return the value of evidenceConfidence
       671  
                *
                */
       672  
                * @param confidence new value of confidence
       673  
                */
               public Confidence getEvidenceConfidence() {
       673  24
                   return evidenceConfidence;
       674  
               public void setConfidence(IdentifierConfidence confidence) {
       675  0
                   this.confidence = confidence;
       676  0
               }
       677  
               /**
       678  
                * The CPE identifier.
       679  
                */
       680  
               private Identifier identifier;
       681  
               }
       675  
       
       682  
       676  
               /**
       683  
                * Get the value of identifier.
       684  
       677  
                * Set the value of evidenceConfidence
       678  
                *
       679  
                * @param evidenceConfidence new value of evidenceConfidence
       680  
                */
       681  
               public void setEvidenceConfidence(Confidence evidenceConfidence) {
       682  0
                   this.evidenceConfidence = evidenceConfidence;
       683  0
               }
       684  
               /**
       685  
                * @return the value of identifier
                * The confidence whether this is an exact match, or a best guess.
       686  
                */
       687  
               public Identifier getIdentifier() {
       688  3
                   return identifier;
               private IdentifierConfidence confidence;
       688  
       
       689  
               }
               /**
       690  
       
                * Get the value of confidence.
       691  
               /**
                *
       692  
                * Set the value of identifier.
                * @return the value of confidence
       693  
                *
                */
       694  
                * @param identifier new value of identifier
       695  
                */
               public IdentifierConfidence getConfidence() {
       695  28
                   return confidence;
       696  
               public void setIdentifier(Identifier identifier) {
       697  0
                   this.identifier = identifier;
       698  0
               }
               }
       697  
       
       698  
               /**
       699  
               //</editor-fold>
                * Set the value of confidence.
       700  
               //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals">
                *
       701  
       
                * @param confidence new value of confidence
       702  
               /**
                */
       703  
                * Standard toString() implementation.
       704  
                *
       705  
                * @return the string representation of the object
               public void setConfidence(IdentifierConfidence confidence) {
       704  0
                   this.confidence = confidence;
       705  0
               }
       706  
                */
               /**
       707  
               @Override
                * The CPE identifier.
       708  
               public String toString() {
       709  0
                   return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence
                */
       709  
               private Identifier identifier;
       710  
                           + ", confidence=" + confidence + ", identifier=" + identifier + '}';
       
       711  
               }
               /**
       712  
       
                * Get the value of identifier.
       713  
               /**
                *
       714  
                * Standard hashCode() implementation.
                * @return the value of identifier
       715  
                *
                */
       716  
                * @return the hashCode
       717  
                */
               public Identifier getIdentifier() {
       717  6
                   return identifier;
       718  
               @Override
               }
       719  
               public int hashCode() {
       720  0
                   int hash = 5;
       721  0
                   hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0);
       722  0
                   hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0);
       723  0
                   hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0);
       724  0
                   return hash;
       
       720  
               /**
       721  
                * Set the value of identifier.
       722  
                *
       723  
                * @param identifier new value of identifier
       724  
                */
       725  
               }
       726  
       
       727  
               /**
               public void setIdentifier(Identifier identifier) {
       726  0
                   this.identifier = identifier;
       727  0
               }
       728  
                * Standard equals implementation.
       729  
                *
       730  
                * @param obj the object to compare
       731  
                * @return true if the objects are equal, otherwise false
       732  
                */
       733  
               @Override
       734  
               public boolean equals(Object obj) {
       735  0
                   if (obj == null) {
       736  0
                       return false;
       737  
                   }
       738  0
                   if (getClass() != obj.getClass()) {
       739  0
                       return false;
       740  
                   }
       741  0
                   final IdentifierMatch other = (IdentifierMatch) obj;
       742  0
                   if (this.evidenceConfidence != other.evidenceConfidence) {
       743  0
                       return false;
       744  
                   }
       745  0
                   if (this.confidence != other.confidence) {
       746  0
                       return false;
       747  
                   }
       748  0
                   if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) {
       749  0
                       return false;
       750  
                   }
       751  0
                   return true;
       752  
               }
       753  
               //</editor-fold>
       754  
       729  
               //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals">
       730  
       
       755  
       731  
               /**
       756  
                * Standard implementation of compareTo that compares identifier confidence, evidence confidence, and then the identifier.
       757  
       732  
                * Standard toString() implementation.
       733  
                *
       758  
                * @param o the IdentifierMatch to compare to
       759  
                * @return the natural ordering of IdentifierMatch
       760  
       734  
                * @return the string representation of the object
       735  
                */
       761  
       736  
               @Override
       737  
               public String toString() {
       738  0
                   return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence
       739  
                           + ", confidence=" + confidence + ", identifier=" + identifier + '}';
       740  
               }
       741  
       
       742  
               /**
       743  
                * Standard hashCode() implementation.
       744  
                *
       745  
                * @return the hashCode
       746  
                */
       747  
               @Override
       748  
               public int hashCode() {
       749  0
                   int hash = 5;
       750  0
                   hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0);
       751  0
                   hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0);
       752  0
                   hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0);
       753  0
                   return hash;
       754  
               }
       755  
       
       756  
               /**
       757  
                * Standard equals implementation.
       758  
                *
       759  
                * @param obj the object to compare
       760  
                * @return true if the objects are equal, otherwise false
       761  
                */
       762  
               public int compareTo(IdentifierMatch o) {
       763  8
                   int conf = this.confidence.compareTo(o.confidence);
       764  8
                   if (conf == 0) {
       765  6
                       conf = this.evidenceConfidence.compareTo(o.evidenceConfidence);
       766  6
                       if (conf == 0) {
       767  2
                           conf = identifier.compareTo(o.identifier);
       768  
                       }
               @Override
       763  
               public boolean equals(Object obj) {
       764  0
                   if (obj == null) {
       765  0
                       return false;
       766  
                   }
       767  0
                   if (getClass() != obj.getClass()) {
       768  0
                       return false;
       769  
                   }
       770  8
                   return conf;
       771  
               }
       772  
           }
       770  0
                   final IdentifierMatch other = (IdentifierMatch) obj;
       771  0
                   if (this.evidenceConfidence != other.evidenceConfidence) {
       772  0
                       return false;
       773  
                   }
       774  0
                   if (this.confidence != other.confidence) {
       775  0
                       return false;
       776  
                   }
       777  0
                   if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) {
       778  0
                       return false;
       779  
                   }
       780  0
                   return true;
       781  
               }
       782  
               //</editor-fold>
       783  
       
       784  
               /**
       785  
                * Standard implementation of compareTo that compares identifier
       786  
                * confidence, evidence confidence, and then the identifier.
       787  
                *
       788  
                * @param o the IdentifierMatch to compare to
       789  
                * @return the natural ordering of IdentifierMatch
       790  
                */
       791  
               @Override
       792  
               public int compareTo(IdentifierMatch o) {
       793  16
                   int conf = this.confidence.compareTo(o.confidence);
       794  16
                   if (conf == 0) {
       795  12
                       conf = this.evidenceConfidence.compareTo(o.evidenceConfidence);
       796  12
                       if (conf == 0) {
       797  4
                           conf = identifier.compareTo(o.identifier);
       798  
                       }
       799  
                   }
       800  16
                   return conf;
       801  
               }
       802  
           }
       803  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html index 808d5e971..9133028c9 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html @@ -115,7 +115,7 @@
        * @author colezlaw
       49  
        */
      -  50  4
       public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
      +  50  12
       public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
       51  
       
       52   @@ -124,7 +124,7 @@
            * The logger.
       54  
            */
      -  55  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class);
      +  55  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class);
       56  
       
       57   @@ -143,7 +143,7 @@
            * The phase in which this analyzer runs.
       64  
            */
      -  65  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  65  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       66  
       
       67   @@ -162,7 +162,7 @@
            * The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has occurred.
       74  
            */
      -  75  4
           private boolean errorFlag = false;
      +  75  12
           private boolean errorFlag = false;
       76  
       
       77   @@ -179,7 +179,7 @@
            * Field indicating if the analyzer is enabled.
       83  
            */
      -  84  4
           private final boolean enabled = checkEnabled();
      +  84  12
           private final boolean enabled = checkEnabled();
       85  
       
       86   @@ -213,16 +213,16 @@
            */
       101  
           private boolean checkEnabled() {
      -  102  4
               boolean retval = false;
      +  102  12
               boolean retval = false;
       103  
       
       104  
               try {
      -  105  4
                   if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
      -  106  3
                       if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
      +  105  12
                   if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
      +  106  8
                       if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
       107  0
                               || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) {
      -  108  3
                           LOGGER.debug("Enabling the Central analyzer");
      -  109  3
                           retval = true;
      +  108  8
                           LOGGER.debug("Enabling the Central analyzer");
      +  109  8
                           retval = true;
       110  
                       } else {
       111  0
                           LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer");
      @@ -230,13 +230,13 @@
                       }
       113  
                   } else {
      -  114  1
                       LOGGER.info("Central analyzer disabled");
      +  114  4
                       LOGGER.info("Central analyzer disabled");
       115  
                   }
       116  0
               } catch (InvalidSettingException ise) {
       117  0
                   LOGGER.warn("Invalid setting. Disabling the Central analyzer");
      -  118  4
               }
      -  119  4
               return retval;
      +  118  12
               }
      +  119  12
               return retval;
       120  
           }
       121   @@ -280,7 +280,7 @@
           @Override
       144  
           public String getName() {
      -  145  4
               return ANALYZER_NAME;
      +  145  32
               return ANALYZER_NAME;
       146  
           }
       147   @@ -299,7 +299,7 @@
           @Override
       154  
           protected String getAnalyzerEnabledSettingKey() {
      -  155  4
               return Settings.KEYS.ANALYZER_CENTRAL_ENABLED;
      +  155  12
               return Settings.KEYS.ANALYZER_CENTRAL_ENABLED;
       156  
           }
       157   @@ -318,7 +318,7 @@
           @Override
       164  
           public AnalysisPhase getAnalysisPhase() {
      -  165  3
               return ANALYSIS_PHASE;
      +  165  8
               return ANALYSIS_PHASE;
       166  
           }
       167   @@ -329,14 +329,14 @@
            * The file filter used to determine which files this analyzer supports.
       170  
            */
      -  171  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
      +  171  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
       172  
       
       173  
           @Override
       174  
           protected FileFilter getFileFilter() {
      -  175  853
               return FILTER;
      +  175  1718
               return FILTER;
       176  
           }
       177   @@ -426,6 +426,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer.html index 2e16a2042..3f5108ad8 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer.html @@ -103,209 +103,211 @@
        * @author colezlaw
       43  
        */
      -  44  7
       public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer {
      -  45   -
       
      +  44   +
       @Experimental
      +  45  18
       public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer {
       46   -
           /**
      +
       
       47   -
            * The logger.
      +
           /**
       48   +
            * The logger.
      +  49  
            */
      -  49  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class);
      -  50   -
       
      +  50  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class);
       51   -
           /**
      +
       
       52   -
            * The analyzer name.
      +
           /**
       53   -
            */
      +
            * The analyzer name.
       54   -
           private static final String ANALYZER_NAME = "Composer.lock analyzer";
      +
            */
       55   -
       
      +
           private static final String ANALYZER_NAME = "Composer.lock analyzer";
       56   -
           /**
      +
       
       57   -
            * composer.json.
      +
           /**
       58   -
            */
      +
            * composer.json.
       59   -
           private static final String COMPOSER_LOCK = "composer.lock";
      +
            */
       60   -
       
      +
           private static final String COMPOSER_LOCK = "composer.lock";
       61   -
           /**
      +
       
       62   -
            * The FileFilter.
      +
           /**
       63   +
            * The FileFilter.
      +  64  
            */
      -  64  1
           private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build();
      -  65   -
       
      +  65  2
           private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build();
       66   -
           /**
      +
       
       67   -
            * Returns the FileFilter.
      +
           /**
       68   -
            *
      +
            * Returns the FileFilter.
       69   -
            * @return the FileFilter
      +
            *
       70   -
            */
      +
            * @return the FileFilter
       71   -
           @Override
      +
            */
       72   +
           @Override
      +  73  
           protected FileFilter getFileFilter() {
      -  73  854
               return FILE_FILTER;
      -  74   -
           }
      +  74  1720
               return FILE_FILTER;
       75   -
       
      +
           }
       76   -
           /**
      +
       
       77   -
            * Initializes the analyzer.
      +
           /**
       78   -
            *
      +
            * Initializes the analyzer.
       79   -
            * @throws Exception thrown if an exception occurs getting an instance of SHA1
      +
            *
       80   -
            */
      +
            * @throws Exception thrown if an exception occurs getting an instance of SHA1
       81   -
           @Override
      +
            */
       82   +
           @Override
      +  83  
           protected void initializeFileTypeAnalyzer() throws Exception {
      -  83  3
               sha1 = MessageDigest.getInstance("SHA1");
      -  84  3
           }
      -  85   -
       
      +  84  6
               sha1 = MessageDigest.getInstance("SHA1");
      +  85  6
           }
       86   -
           /**
      +
       
       87   -
            * The MessageDigest for calculating a new digest for the new dependencies added.
      +
           /**
       88   +
            * The MessageDigest for calculating a new digest for the new dependencies added.
      +  89  
            */
      -  89  7
           private MessageDigest sha1 = null;
      -  90   -
       
      +  90  18
           private MessageDigest sha1 = null;
       91   -
           /**
      +
       
       92   -
            * Entry point for the analyzer.
      +
           /**
       93   -
            *
      +
            * Entry point for the analyzer.
       94   -
            * @param dependency the dependency to analyze
      +
            *
       95   -
            * @param engine the engine scanning
      +
            * @param dependency the dependency to analyze
       96   -
            * @throws AnalysisException if there's a failure during analysis
      +
            * @param engine the engine scanning
       97   -
            */
      +
            * @throws AnalysisException if there's a failure during analysis
       98   -
           @Override
      +
            */
       99   +
           @Override
      +  100  
           protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      -  100  1
               FileInputStream fis = null;
      -  101   +  101  2
               FileInputStream fis = null;
      +  102  
               try {
      -  102  1
                   fis = new FileInputStream(dependency.getActualFile());
      -  103  1
                   final ComposerLockParser clp = new ComposerLockParser(fis);
      -  104  1
                   LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath());
      -  105  1
                   clp.process();
      -  106  1
                   for (ComposerDependency dep : clp.getDependencies()) {
      -  107  30
                       final Dependency d = new Dependency(dependency.getActualFile());
      -  108  30
                       d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject()));
      -  109  30
                       final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject());
      -  110  30
                       d.setFilePath(filePath);
      -  111  30
                       d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset()))));
      -  112  30
                       d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST);
      -  113  30
                       d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST);
      -  114  30
                       d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST);
      -  115  30
                       LOGGER.info("Adding dependency {}", d);
      -  116  30
                       engine.getDependencies().add(d);
      -  117  30
                   }
      -  118  0
               } catch (FileNotFoundException fnfe) {
      -  119  0
                   LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath());
      -  120  0
               } catch (ComposerException ce) {
      -  121  0
                   LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce);
      -  122   +  103  2
                   fis = new FileInputStream(dependency.getActualFile());
      +  104  2
                   final ComposerLockParser clp = new ComposerLockParser(fis);
      +  105  2
                   LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath());
      +  106  2
                   clp.process();
      +  107  2
                   for (ComposerDependency dep : clp.getDependencies()) {
      +  108  60
                       final Dependency d = new Dependency(dependency.getActualFile());
      +  109  60
                       d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject()));
      +  110  60
                       final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject());
      +  111  60
                       d.setFilePath(filePath);
      +  112  60
                       d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset()))));
      +  113  60
                       d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST);
      +  114  60
                       d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST);
      +  115  60
                       d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST);
      +  116  60
                       LOGGER.info("Adding dependency {}", d);
      +  117  60
                       engine.getDependencies().add(d);
      +  118  60
                   }
      +  119  0
               } catch (FileNotFoundException fnfe) {
      +  120  0
                   LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath());
      +  121  0
               } catch (ComposerException ce) {
      +  122  0
                   LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce);
      +  123  
               } finally {
      -  123  1
                   if (fis != null) {
      -  124   +  124  2
                   if (fis != null) {
      +  125  
                       try {
      -  125  1
                           fis.close();
      -  126  0
                       } catch (Exception e) {
      -  127  0
                           LOGGER.debug("Unable to close file", e);
      -  128  1
                       }
      -  129   -
                   }
      +  126  2
                           fis.close();
      +  127  0
                       } catch (Exception e) {
      +  128  0
                           LOGGER.debug("Unable to close file", e);
      +  129  2
                       }
       130   +
                   }
      +  131  
               }
      -  131  1
           }
      -  132   -
       
      +  132  2
           }
       133   -
           /**
      +
       
       134   -
            * Gets the key to determine whether the analyzer is enabled.
      +
           /**
       135   -
            *
      +
            * Gets the key to determine whether the analyzer is enabled.
       136   -
            * @return the key specifying whether the analyzer is enabled
      +
            *
       137   -
            */
      +
            * @return the key specifying whether the analyzer is enabled
       138   -
           @Override
      +
            */
       139   +
           @Override
      +  140  
           protected String getAnalyzerEnabledSettingKey() {
      -  140  7
               return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED;
      -  141   -
           }
      +  141  18
               return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED;
       142   -
       
      +
           }
       143   -
           /**
      -  144   -
            * Returns the analyzer's name.
      -  145   -
            *
      -  146   -
            * @return the analyzer's name
      -  147   -
            */
      -  148   -
           @Override
      -  149   -
           public String getName() {
      -  150  5
               return ANALYZER_NAME;
      -  151   -
           }
      -  152  
       
      -  153   +  144  
           /**
      -  154   -
            * Returns the phase this analyzer should run under.
      -  155   +  145   +
            * Returns the analyzer's name.
      +  146  
            *
      -  156   -
            * @return the analysis phase
      -  157   +  147   +
            * @return the analyzer's name
      +  148  
            */
      -  158   +  149  
           @Override
      -  159   -
           public AnalysisPhase getAnalysisPhase() {
      -  160  3
               return AnalysisPhase.INFORMATION_COLLECTION;
      -  161   +  150   +
           public String getName() {
      +  151  30
               return ANALYZER_NAME;
      +  152  
           }
      +  153   +
       
      +  154   +
           /**
      +  155   +
            * Returns the phase this analyzer should run under.
      +  156   +
            *
      +  157   +
            * @return the analysis phase
      +  158   +
            */
      +  159   +
           @Override
      +  160   +
           public AnalysisPhase getAnalysisPhase() {
      +  161  8
               return AnalysisPhase.INFORMATION_COLLECTION;
       162   +
           }
      +  163  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer.html index d132d93eb..bee0838f0 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer.html @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  4
       public class CpeSuppressionAnalyzer extends AbstractSuppressionAnalyzer {
      +  31  12
       public class CpeSuppressionAnalyzer extends AbstractSuppressionAnalyzer {
       32  
       
       33   @@ -96,7 +96,7 @@
            * The phase that this analyzer is intended to run in.
       40  
            */
      -  41  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
      +  41  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
       42  
       
       43   @@ -113,7 +113,7 @@
           @Override
       49  
           public String getName() {
      -  50  4
               return ANALYZER_NAME;
      +  50  32
               return ANALYZER_NAME;
       51  
           }
       52   @@ -132,7 +132,7 @@
           @Override
       59  
           public AnalysisPhase getAnalysisPhase() {
      -  60  3
               return ANALYSIS_PHASE;
      +  60  8
               return ANALYSIS_PHASE;
       61  
           }
       62   @@ -145,20 +145,20 @@
           public void analyze(final Dependency dependency, final Engine engine) throws AnalysisException {
       66  
       
      -  67  2
               if (getRules() == null || getRules().size() <= 0) {
      +  67  8
               if (getRules() == null || getRules().size() <= 0) {
       68  0
                   return;
       69  
               }
       70  
       
      -  71  2
               for (final SuppressionRule rule : getRules()) {
      -  72  84
                   rule.process(dependency);
      -  73  84
               }
      -  74  2
           }
      +  71  8
               for (final SuppressionRule rule : getRules()) {
      +  72  440
                   rule.process(dependency);
      +  73  440
               }
      +  74  8
           }
       75  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer.html index c57d711ea..ac30c27e3 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      DependencyBundlingAnalyzer
      43%
      68/156
      31%
      51/160
      7.5
      DependencyBundlingAnalyzer
      40%
      72/178
      30%
      57/184
      7.688
       
      @@ -92,633 +92,767 @@  37  
        * <p>
       38   -
        * This analyzer ensures dependencies that should be grouped together, to remove excess noise from the report, are grouped. An
      +
        * This analyzer ensures dependencies that should be grouped together, to remove
       39   -
        * example would be Spring, Spring Beans, Spring MVC, etc. If they are all for the same version and have the same relative path
      +
        * excess noise from the report, are grouped. An example would be Spring, Spring
       40   -
        * then these should be grouped into a single dependency under the core/main library.</p>
      +
        * Beans, Spring MVC, etc. If they are all for the same version and have the
       41   -
        * <p>
      +
        * same relative path then these should be grouped into a single dependency
       42   -
        * Note, this grouping only works on dependencies with identified CVE entries</p>
      +
        * under the core/main library.</p>
       43   -
        *
      +
        * <p>
       44   -
        * @author Jeremy Long
      +
        * Note, this grouping only works on dependencies with identified CVE
       45   -
        */
      -  46  8
       public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer {
      +
        * entries</p>
      +  46   +
        *
       47   -
       
      +
        * @author Jeremy Long
       48   -
           /**
      -  49   -
            * The Logger.
      +
        */
      +  49  20
       public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer {
       50   -
            */
      -  51  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class);
      +
       
      +  51   +
           /**
       52   -
       
      +
            * The Logger.
       53   -
           //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
      -  54   -
           /**
      +
            */
      +  54  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class);
       55   -
            * A pattern for obtaining the first part of a filename.
      +
       
       56   -
            */
      -  57  1
           private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*");
      +
           //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
      +  57   +
           /**
       58   -
           /**
      +
            * A pattern for obtaining the first part of a filename.
       59   -
            * a flag indicating if this analyzer has run. This analyzer only runs once.
      -  60  
            */
      -  61  8
           private boolean analyzed = false;
      +  60  2
           private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*");
      +  61   +
           /**
       62   -
           //</editor-fold>
      +
            * a flag indicating if this analyzer has run. This analyzer only runs once.
       63   -
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
      -  64   -
           /**
      +
            */
      +  64  20
           private boolean analyzed = false;
       65   -
            * The name of the analyzer.
      -  66   -
            */
      -  67   -
           private static final String ANALYZER_NAME = "Dependency Bundling Analyzer";
      -  68   -
           /**
      -  69   -
            * The phase that this analyzer is intended to run in.
      -  70   -
            */
      -  71  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
      -  72   -
       
      -  73   -
           /**
      -  74   -
            * Returns the name of the analyzer.
      -  75   -
            *
      -  76   -
            * @return the name of the analyzer.
      -  77   -
            */
      -  78   -
           @Override
      -  79   -
           public String getName() {
      -  80  5
               return ANALYZER_NAME;
      -  81   -
           }
      -  82   -
       
      -  83   -
           /**
      -  84   -
            * Returns the phase that the analyzer is intended to run in.
      -  85   -
            *
      -  86   -
            * @return the phase that the analyzer is intended to run in.
      -  87   -
            */
      -  88   -
           @Override
      -  89   -
           public AnalysisPhase getAnalysisPhase() {
      -  90  4
               return ANALYSIS_PHASE;
      -  91   -
           }
      -  92  
           //</editor-fold>
      -  93   -
       
      -  94   +  66   +
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
      +  67  
           /**
      -  95   -
            * Analyzes a set of dependencies. If they have been found to have the same base path and the same set of identifiers they are
      -  96   -
            * likely related. The related dependencies are bundled into a single reportable item.
      -  97   -
            *
      -  98   -
            * @param ignore this analyzer ignores the dependency being analyzed
      -  99   -
            * @param engine the engine that is scanning the dependencies
      -  100   -
            * @throws AnalysisException is thrown if there is an error reading the JAR file.
      -  101   +  68   +
            * The name of the analyzer.
      +  69  
            */
      -  102   +  70   +
           private static final String ANALYZER_NAME = "Dependency Bundling Analyzer";
      +  71   +
           /**
      +  72   +
            * The phase that this analyzer is intended to run in.
      +  73   +
            */
      +  74  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
      +  75   +
       
      +  76   +
           /**
      +  77   +
            * Returns the name of the analyzer.
      +  78   +
            *
      +  79   +
            * @return the name of the analyzer.
      +  80   +
            */
      +  81  
           @Override
      +  82   +
           public String getName() {
      +  83  34
               return ANALYZER_NAME;
      +  84   +
           }
      +  85   +
       
      +  86   +
           /**
      +  87   +
            * Returns the phase that the analyzer is intended to run in.
      +  88   +
            *
      +  89   +
            * @return the phase that the analyzer is intended to run in.
      +  90   +
            */
      +  91   +
           @Override
      +  92   +
           public AnalysisPhase getAnalysisPhase() {
      +  93  10
               return ANALYSIS_PHASE;
      +  94   +
           }
      +  95   +
           //</editor-fold>
      +  96   +
       
      +  97   +
           /**
      +  98   +
            * Analyzes a set of dependencies. If they have been found to have the same
      +  99   +
            * base path and the same set of identifiers they are likely related. The
      +  100   +
            * related dependencies are bundled into a single reportable item.
      +  101   +
            *
      +  102   +
            * @param ignore this analyzer ignores the dependency being analyzed
       103   -
           public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
      -  104  2
               if (!analyzed) {
      -  105  1
                   analyzed = true;
      -  106  1
                   final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
      -  107  1
                   final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
      +
            * @param engine the engine that is scanning the dependencies
      +  104   +
            * @throws AnalysisException is thrown if there is an error reading the JAR
      +  105   +
            * file.
      +  106   +
            */
      +  107   +
           @Override
       108   +
           public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
      +  109  8
               if (!analyzed) {
      +  110  4
                   analyzed = true;
      +  111  4
                   final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
      +  112  4
                   final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
      +  113  
                   //for (Dependency nextDependency : engine.getDependencies()) {
      -  109  3
                   while (mainIterator.hasNext()) {
      -  110  2
                       final Dependency dependency = mainIterator.next();
      -  111  2
                       if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) {
      -  112  1
                           final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
      -  113  2
                           while (subIterator.hasNext()) {
      -  114  1
                               final Dependency nextDependency = subIterator.next();
      -  115  1
                               if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath())
      -  116  0
                                       && !containedInWar(nextDependency.getFilePath())) {
      -  117  0
                                   if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) {
      -  118  0
                                       mergeDependencies(dependency, nextDependency, dependenciesToRemove);
      -  119   +  114  12
                   while (mainIterator.hasNext()) {
      +  115  8
                       final Dependency dependency = mainIterator.next();
      +  116  8
                       if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) {
      +  117  4
                           final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
      +  118  8
                           while (subIterator.hasNext()) {
      +  119  4
                               final Dependency nextDependency = subIterator.next();
      +  120  4
                               if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath())
      +  121  0
                                       && !containedInWar(nextDependency.getFilePath())) {
      +  122  0
                                   if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) {
      +  123  0
                                       mergeDependencies(dependency, nextDependency, dependenciesToRemove);
      +  124  
                                   } else {
      -  120  0
                                       mergeDependencies(nextDependency, dependency, dependenciesToRemove);
      -  121  0
                                       break; //since we merged into the next dependency - skip forward to the next in mainIterator
      -  122   -
                                   }
      -  123  1
                               } else if (isShadedJar(dependency, nextDependency)) {
      -  124  0
                                   if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) {
       125  0
                                       mergeDependencies(nextDependency, dependency, dependenciesToRemove);
      -  126  0
                                       nextDependency.getRelatedDependencies().remove(dependency);
      -  127  0
                                       break;
      -  128   -
                                   } else {
      -  129  0
                                       mergeDependencies(dependency, nextDependency, dependenciesToRemove);
      -  130  0
                                       dependency.getRelatedDependencies().remove(nextDependency);
      -  131   +  126  0
                                       break; //since we merged into the next dependency - skip forward to the next in mainIterator
      +  127  
                                   }
      -  132  1
                               } else if (cpeIdentifiersMatch(dependency, nextDependency)
      -  133  0
                                       && hasSameBasePath(dependency, nextDependency)
      -  134  0
                                       && fileNameMatch(dependency, nextDependency)) {
      -  135  0
                                   if (isCore(dependency, nextDependency)) {
      -  136  0
                                       mergeDependencies(dependency, nextDependency, dependenciesToRemove);
      -  137   +  128  4
                               } else if (isShadedJar(dependency, nextDependency)) {
      +  129  0
                                   if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) {
      +  130  0
                                       mergeDependencies(nextDependency, dependency, dependenciesToRemove);
      +  131  0
                                       nextDependency.getRelatedDependencies().remove(dependency);
      +  132  0
                                       break;
      +  133  
                                   } else {
      -  138  0
                                       mergeDependencies(nextDependency, dependency, dependenciesToRemove);
      -  139  0
                                       break; //since we merged into the next dependency - skip forward to the next in mainIterator
      -  140   +  134  0
                                       mergeDependencies(dependency, nextDependency, dependenciesToRemove);
      +  135  0
                                       dependency.getRelatedDependencies().remove(nextDependency);
      +  136  
                                   }
      -  141   -
                               }
      -  142  1
                           }
      -  143   -
                       }
      -  144  2
                   }
      +  137  4
                               } else if (cpeIdentifiersMatch(dependency, nextDependency)
      +  138  0
                                       && hasSameBasePath(dependency, nextDependency)
      +  139  0
                                       && fileNameMatch(dependency, nextDependency)) {
      +  140  0
                                   if (isCore(dependency, nextDependency)) {
      +  141  0
                                       mergeDependencies(dependency, nextDependency, dependenciesToRemove);
      +  142   +
                                   } else {
      +  143  0
                                       mergeDependencies(nextDependency, dependency, dependenciesToRemove);
      +  144  0
                                       break; //since we merged into the next dependency - skip forward to the next in mainIterator
       145   -
                   //removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions
      -  146   -
                   // was difficult because of the inner iterator.
      -  147  1
                   engine.getDependencies().removeAll(dependenciesToRemove);
      -  148   -
               }
      -  149  2
           }
      +
                                   }
      +  146  4
                               } else if (isSameRubyGem(dependency, nextDependency)) {
      +  147  0
                                   final Dependency main = getMainGemspecDependency(dependency, nextDependency);
      +  148  0
                                   if (main == dependency) {
      +  149  0
                                       mergeDependencies(dependency, nextDependency, dependenciesToRemove);
       150   -
       
      -  151   -
           /**
      -  152   -
            * Adds the relatedDependency to the dependency's related dependencies.
      +
                                   } else {
      +  151  0
                                       mergeDependencies(nextDependency, dependency, dependenciesToRemove);
      +  152  0
                                       break; //since we merged into the next dependency - skip forward to the next in mainIterator
       153   -
            *
      +
                                   }
       154   -
            * @param dependency the main dependency
      -  155   -
            * @param relatedDependency a collection of dependencies to be removed from the main analysis loop, this is the source of
      +
                               }
      +  155  4
                           }
       156   -
            * dependencies to remove
      -  157   -
            * @param dependenciesToRemove a collection of dependencies that will be removed from the main analysis loop, this function
      +
                       }
      +  157  8
                   }
       158   -
            * adds to this collection
      +
                   //removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions
       159   -
            */
      -  160   -
           private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
      -  161  0
               dependency.addRelatedDependency(relatedDependency);
      -  162  0
               final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator();
      -  163  0
               while (i.hasNext()) {
      -  164  0
                   dependency.addRelatedDependency(i.next());
      -  165  0
                   i.remove();
      -  166   +
                   // was difficult because of the inner iterator.
      +  160  4
                   engine.getDependencies().removeAll(dependenciesToRemove);
      +  161  
               }
      -  167  0
               if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) {
      -  168  0
                   dependency.addAllProjectReferences(relatedDependency.getProjectReferences());
      -  169   -
               }
      -  170  0
               dependenciesToRemove.add(relatedDependency);
      -  171  0
           }
      -  172   +  162  8
           }
      +  163  
       
      -  173   +  164  
           /**
      -  174   -
            * Attempts to trim a maven repo to a common base path. This is typically [drive]\[repo_location]\repository\[path1]\[path2].
      -  175   +  165   +
            * Adds the relatedDependency to the dependency's related dependencies.
      +  166  
            *
      -  176   -
            * @param path the path to trim
      -  177   -
            * @return a string representing the base path.
      -  178   +  167   +
            * @param dependency the main dependency
      +  168   +
            * @param relatedDependency a collection of dependencies to be removed from
      +  169   +
            * the main analysis loop, this is the source of dependencies to remove
      +  170   +
            * @param dependenciesToRemove a collection of dependencies that will be
      +  171   +
            * removed from the main analysis loop, this function adds to this
      +  172   +
            * collection
      +  173  
            */
      -  179   -
           private String getBaseRepoPath(final String path) {
      -  180  0
               int pos = path.indexOf("repository" + File.separator) + 11;
      -  181  0
               if (pos < 0) {
      -  182  0
                   return path;
      +  174   +
           private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
      +  175  0
               dependency.addRelatedDependency(relatedDependency);
      +  176  0
               final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator();
      +  177  0
               while (i.hasNext()) {
      +  178  0
                   dependency.addRelatedDependency(i.next());
      +  179  0
                   i.remove();
      +  180   +
               }
      +  181  0
               if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) {
      +  182  0
                   dependency.addAllProjectReferences(relatedDependency.getProjectReferences());
       183  
               }
      -  184  0
               int tmp = path.indexOf(File.separator, pos);
      -  185  0
               if (tmp <= 0) {
      -  186  0
                   return path;
      -  187   -
               }
      -  188  0
               if (tmp > 0) {
      -  189  0
                   pos = tmp + 1;
      -  190   -
               }
      -  191  0
               tmp = path.indexOf(File.separator, pos);
      -  192  0
               if (tmp > 0) {
      -  193  0
                   pos = tmp + 1;
      -  194   -
               }
      -  195  0
               return path.substring(0, pos);
      -  196   -
           }
      -  197   +  184  0
               dependenciesToRemove.add(relatedDependency);
      +  185  0
           }
      +  186  
       
      -  198   +  187  
           /**
      -  199   -
            * Returns true if the file names (and version if it exists) of the two dependencies are sufficiently similar.
      -  200   +  188   +
            * Attempts to trim a maven repo to a common base path. This is typically
      +  189   +
            * [drive]\[repo_location]\repository\[path1]\[path2].
      +  190  
            *
      -  201   -
            * @param dependency1 a dependency2 to compare
      -  202   -
            * @param dependency2 a dependency2 to compare
      -  203   -
            * @return true if the identifiers in the two supplied dependencies are equal
      -  204   +  191   +
            * @param path the path to trim
      +  192   +
            * @return a string representing the base path.
      +  193  
            */
      +  194   +
           private String getBaseRepoPath(final String path) {
      +  195  0
               int pos = path.indexOf("repository" + File.separator) + 11;
      +  196  0
               if (pos < 0) {
      +  197  0
                   return path;
      +  198   +
               }
      +  199  0
               int tmp = path.indexOf(File.separator, pos);
      +  200  0
               if (tmp <= 0) {
      +  201  0
                   return path;
      +  202   +
               }
      +  203  0
               if (tmp > 0) {
      +  204  0
                   pos = tmp + 1;
       205   -
           private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) {
      -  206  0
               if (dependency1 == null || dependency1.getFileName() == null
      -  207  0
                       || dependency2 == null || dependency2.getFileName() == null) {
      -  208  0
                   return false;
      +
               }
      +  206  0
               tmp = path.indexOf(File.separator, pos);
      +  207  0
               if (tmp > 0) {
      +  208  0
                   pos = tmp + 1;
       209  
               }
      -  210  0
               final String fileName1 = dependency1.getActualFile().getName();
      -  211  0
               final String fileName2 = dependency2.getActualFile().getName();
      +  210  0
               return path.substring(0, pos);
      +  211   +
           }
       212  
       
       213   -
               //version check
      -  214  0
               final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1);
      -  215  0
               final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2);
      -  216  0
               if (version1 != null && version2 != null && !version1.equals(version2)) {
      -  217  0
                   return false;
      +
           /**
      +  214   +
            * Returns true if the file names (and version if it exists) of the two
      +  215   +
            * dependencies are sufficiently similar.
      +  216   +
            *
      +  217   +
            * @param dependency1 a dependency2 to compare
       218   -
               }
      +
            * @param dependency2 a dependency2 to compare
       219   -
       
      +
            * @return true if the identifiers in the two supplied dependencies are
       220   -
               //filename check
      -  221  0
               final Matcher match1 = STARTING_TEXT_PATTERN.matcher(fileName1);
      -  222  0
               final Matcher match2 = STARTING_TEXT_PATTERN.matcher(fileName2);
      -  223  0
               if (match1.find() && match2.find()) {
      -  224  0
                   return match1.group().equals(match2.group());
      -  225   -
               }
      +
            * equal
      +  221   +
            */
      +  222   +
           private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) {
      +  223  0
               if (dependency1 == null || dependency1.getFileName() == null
      +  224  0
                       || dependency2 == null || dependency2.getFileName() == null) {
      +  225  0
                   return false;
       226   -
       
      -  227  0
               return false;
      -  228   -
           }
      +
               }
      +  227  0
               final String fileName1 = dependency1.getActualFile().getName();
      +  228  0
               final String fileName2 = dependency2.getActualFile().getName();
       229  
       
       230   -
           /**
      -  231   -
            * Returns true if the CPE identifiers in the two supplied dependencies are equal.
      -  232   -
            *
      -  233   -
            * @param dependency1 a dependency2 to compare
      -  234   -
            * @param dependency2 a dependency2 to compare
      +
               //version check
      +  231  0
               final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1);
      +  232  0
               final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2);
      +  233  0
               if (version1 != null && version2 != null && !version1.equals(version2)) {
      +  234  0
                   return false;
       235   -
            * @return true if the identifiers in the two supplied dependencies are equal
      +
               }
       236   -
            */
      +
       
       237   -
           private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) {
      -  238  1
               if (dependency1 == null || dependency1.getIdentifiers() == null
      -  239  1
                       || dependency2 == null || dependency2.getIdentifiers() == null) {
      -  240  0
                   return false;
      -  241   +
               //filename check
      +  238  0
               final Matcher match1 = STARTING_TEXT_PATTERN.matcher(fileName1);
      +  239  0
               final Matcher match2 = STARTING_TEXT_PATTERN.matcher(fileName2);
      +  240  0
               if (match1.find() && match2.find()) {
      +  241  0
                   return match1.group().equals(match2.group());
      +  242  
               }
      -  242  1
               boolean matches = false;
      -  243  1
               int cpeCount1 = 0;
      -  244  1
               int cpeCount2 = 0;
      -  245  1
               for (Identifier i : dependency1.getIdentifiers()) {
      -  246  0
                   if ("cpe".equals(i.getType())) {
      -  247  0
                       cpeCount1 += 1;
      +  243   +
       
      +  244  0
               return false;
      +  245   +
           }
      +  246   +
       
      +  247   +
           /**
       248   -
                   }
      -  249  0
               }
      -  250  1
               for (Identifier i : dependency2.getIdentifiers()) {
      -  251  3
                   if ("cpe".equals(i.getType())) {
      -  252  3
                       cpeCount2 += 1;
      +
            * Returns true if the CPE identifiers in the two supplied dependencies are
      +  249   +
            * equal.
      +  250   +
            *
      +  251   +
            * @param dependency1 a dependency2 to compare
      +  252   +
            * @param dependency2 a dependency2 to compare
       253   -
                   }
      -  254  3
               }
      -  255  1
               if (cpeCount1 > 0 && cpeCount1 == cpeCount2) {
      -  256  0
                   for (Identifier i : dependency1.getIdentifiers()) {
      -  257  0
                       if ("cpe".equals(i.getType())) {
      -  258  0
                           matches |= dependency2.getIdentifiers().contains(i);
      -  259  0
                           if (!matches) {
      -  260  0
                               break;
      -  261   -
                           }
      -  262   -
                       }
      -  263  0
                   }
      -  264   +
            * @return true if the identifiers in the two supplied dependencies are
      +  254   +
            * equal
      +  255   +
            */
      +  256   +
           private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) {
      +  257  4
               if (dependency1 == null || dependency1.getIdentifiers() == null
      +  258  4
                       || dependency2 == null || dependency2.getIdentifiers() == null) {
      +  259  0
                   return false;
      +  260  
               }
      -  265  1
               LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName());
      -  266  1
               return matches;
      +  261  4
               boolean matches = false;
      +  262  4
               int cpeCount1 = 0;
      +  263  4
               int cpeCount2 = 0;
      +  264  4
               for (Identifier i : dependency1.getIdentifiers()) {
      +  265  0
                   if ("cpe".equals(i.getType())) {
      +  266  0
                       cpeCount1 += 1;
       267   -
           }
      -  268   -
       
      -  269   -
           /**
      -  270   -
            * Determines if the two dependencies have the same base path.
      -  271   -
            *
      -  272   -
            * @param dependency1 a Dependency object
      -  273   -
            * @param dependency2 a Dependency object
      -  274   -
            * @return true if the base paths of the dependencies are identical
      -  275   -
            */
      -  276   -
           private boolean hasSameBasePath(Dependency dependency1, Dependency dependency2) {
      -  277  0
               if (dependency1 == null || dependency2 == null) {
      -  278  0
                   return false;
      -  279   -
               }
      -  280  0
               final File lFile = new File(dependency1.getFilePath());
      -  281  0
               String left = lFile.getParent();
      -  282  0
               final File rFile = new File(dependency2.getFilePath());
      -  283  0
               String right = rFile.getParent();
      -  284  0
               if (left == null) {
      -  285  0
                   return right == null;
      -  286   -
               }
      -  287  0
               if (left.equalsIgnoreCase(right)) {
      -  288  0
                   return true;
      -  289   -
               }
      -  290  0
               if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) {
      -  291  0
                   left = getBaseRepoPath(left);
      -  292  0
                   right = getBaseRepoPath(right);
      -  293   -
               }
      -  294  0
               if (left.equalsIgnoreCase(right)) {
      -  295  0
                   return true;
      -  296   -
               }
      -  297   -
               //new code
      -  298  0
               for (Dependency child : dependency2.getRelatedDependencies()) {
      -  299  0
                   if (hasSameBasePath(dependency1, child)) {
      -  300  0
                       return true;
      -  301  
                   }
      -  302  0
               }
      -  303  0
               return false;
      -  304   +  268  0
               }
      +  269  4
               for (Identifier i : dependency2.getIdentifiers()) {
      +  270  6
                   if ("cpe".equals(i.getType())) {
      +  271  6
                       cpeCount2 += 1;
      +  272   +
                   }
      +  273  6
               }
      +  274  4
               if (cpeCount1 > 0 && cpeCount1 == cpeCount2) {
      +  275  0
                   for (Identifier i : dependency1.getIdentifiers()) {
      +  276  0
                       if ("cpe".equals(i.getType())) {
      +  277  0
                           matches |= dependency2.getIdentifiers().contains(i);
      +  278  0
                           if (!matches) {
      +  279  0
                               break;
      +  280   +
                           }
      +  281   +
                       }
      +  282  0
                   }
      +  283   +
               }
      +  284  4
               LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName());
      +  285  4
               return matches;
      +  286  
           }
      -  305   +  287  
       
      -  306   +  288  
           /**
      -  307   -
            * This is likely a very broken attempt at determining if the 'left' dependency is the 'core' library in comparison to the
      -  308   -
            * 'right' library.
      -  309   +  289   +
            * Determines if the two dependencies have the same base path.
      +  290  
            *
      -  310   -
            * @param left the dependency to test
      -  311   -
            * @param right the dependency to test against
      -  312   -
            * @return a boolean indicating whether or not the left dependency should be considered the "core" version.
      -  313   +  291   +
            * @param dependency1 a Dependency object
      +  292   +
            * @param dependency2 a Dependency object
      +  293   +
            * @return true if the base paths of the dependencies are identical
      +  294  
            */
      -  314   -
           boolean isCore(Dependency left, Dependency right) {
      -  315  2
               final String leftName = left.getFileName().toLowerCase();
      -  316  2
               final String rightName = right.getFileName().toLowerCase();
      -  317   +  295   +
           private boolean hasSameBasePath(Dependency dependency1, Dependency dependency2) {
      +  296  0
               if (dependency1 == null || dependency2 == null) {
      +  297  0
                   return false;
      +  298   +
               }
      +  299  0
               final File lFile = new File(dependency1.getFilePath());
      +  300  0
               String left = lFile.getParent();
      +  301  0
               final File rFile = new File(dependency2.getFilePath());
      +  302  0
               String right = rFile.getParent();
      +  303  0
               if (left == null) {
      +  304  0
                   return right == null;
      +  305   +
               }
      +  306  0
               if (left.equalsIgnoreCase(right)) {
      +  307  0
                   return true;
      +  308   +
               }
      +  309  0
               if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) {
      +  310  0
                   left = getBaseRepoPath(left);
      +  311  0
                   right = getBaseRepoPath(right);
      +  312   +
               }
      +  313  0
               if (left.equalsIgnoreCase(right)) {
      +  314  0
                   return true;
      +  315   +
               }
      +  316   +
               //new code
      +  317  0
               for (Dependency child : dependency2.getRelatedDependencies()) {
      +  318  0
                   if (hasSameBasePath(dependency1, child)) {
      +  319  0
                       return true;
      +  320   +
                   }
      +  321  0
               }
      +  322  0
               return false;
      +  323   +
           }
      +  324  
       
      -  318   -
               final boolean returnVal;
      -  319  2
               if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
      -  320  2
                       || rightName.contains("core") && !leftName.contains("core")
      -  321  2
                       || rightName.contains("kernel") && !leftName.contains("kernel")) {
      -  322  0
                   returnVal = false;
      -  323  2
               } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
      -  324  1
                       || !rightName.contains("core") && leftName.contains("core")
      -  325  1
                       || !rightName.contains("kernel") && leftName.contains("kernel")) {
      -  326  2
                   returnVal = true;
      +  325   +
           /**
      +  326   +
            * Bundling Ruby gems that are identified from different .gemspec files but
       327   -
       //        } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) {
      +
            * denote the same package path. This happens when Ruby bundler installs an
       328   -
       //            returnVal = true;
      +
            * application's dependencies by running "bundle install".
       329   -
       //        } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) {
      +
            *
       330   -
       //            returnVal = false;
      +
            * @param dependency1 dependency to compare
       331   -
               } else {
      +
            * @param dependency2 dependency to compare
       332   -
                   /*
      +
            * @return true if the the dependencies being analyzed appear to be the
       333   -
                    * considered splitting the names up and comparing the components,
      +
            * same; otherwise false
       334   -
                    * but decided that the file name length should be sufficient as the
      +
            */
       335   -
                    * "core" component, if this follows a normal naming protocol should
      -  336   -
                    * be shorter:
      -  337   -
                    * axis2-saaj-1.4.1.jar
      -  338   -
                    * axis2-1.4.1.jar       <-----
      -  339   -
                    * axis2-kernel-1.4.1.jar
      -  340   -
                    */
      -  341  0
                   returnVal = leftName.length() <= rightName.length();
      +
           private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) {
      +  336  4
               if (dependency1 == null || dependency2 == null
      +  337  4
                       || !dependency1.getFileName().endsWith(".gemspec")
      +  338  0
                       || !dependency2.getFileName().endsWith(".gemspec")
      +  339  0
                       || dependency1.getPackagePath() == null
      +  340  0
                       || dependency2.getPackagePath() == null) {
      +  341  4
                   return false;
       342  
               }
      -  343  2
               LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName());
      -  344  2
               return returnVal;
      +  343  0
               if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath())) {
      +  344  0
                   return true;
       345   -
           }
      +
               }
       346  
       
      -  347   -
           /**
      +  347  0
               return false;
       348   -
            * Compares the SHA1 hashes of two dependencies to determine if they are equal.
      +
           }
       349   -
            *
      +
       
       350   -
            * @param dependency1 a dependency object to compare
      +
           /**
       351   -
            * @param dependency2 a dependency object to compare
      +
            * Ruby gems installed by "bundle install" can have zero or more *.gemspec
       352   -
            * @return true if the sha1 hashes of the two dependencies match; otherwise false
      +
            * files, all of which have the same packagePath and should be grouped. If
       353   -
            */
      +
            * one of these gemspec is from <parent>/specifications/*.gemspec, because
       354   -
           private boolean hashesMatch(Dependency dependency1, Dependency dependency2) {
      -  355  1
               if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) {
      -  356  0
                   return false;
      +
            * it is a stub with fully resolved gem meta-data created by Ruby bundler,
      +  355   +
            * this dependency should be the main one. Otherwise, use dependency2 as
      +  356   +
            * main.
       357   -
               }
      -  358  1
               return dependency1.getSha1sum().equals(dependency2.getSha1sum());
      +
            *
      +  358   +
            * This method returns null if any dependency is not from *.gemspec, or the
       359   -
           }
      +
            * two do not have the same packagePath. In this case, they should not be
       360   -
       
      +
            * grouped.
       361   -
           /**
      +
            *
       362   -
            * Determines if the jar is shaded and the created pom.xml identified the same CPE as the jar - if so, the pom.xml dependency
      +
            * @param dependency1 dependency to compare
       363   -
            * should be removed.
      +
            * @param dependency2 dependency to compare
       364   -
            *
      +
            * @return the main dependency; or null if a gemspec is not included in the
       365   -
            * @param dependency a dependency to check
      +
            * analysis
       366   -
            * @param nextDependency another dependency to check
      -  367   -
            * @return true if on of the dependencies is a pom.xml and the identifiers between the two collections match; otherwise false
      -  368  
            */
      -  369   -
           private boolean isShadedJar(Dependency dependency, Dependency nextDependency) {
      -  370  1
               final String mainName = dependency.getFileName().toLowerCase();
      -  371  1
               final String nextName = nextDependency.getFileName().toLowerCase();
      -  372  1
               if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) {
      -  373  0
                   return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers());
      -  374  1
               } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) {
      -  375  0
                   return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers());
      -  376   +  367   +
           private Dependency getMainGemspecDependency(Dependency dependency1, Dependency dependency2) {
      +  368  0
               if (isSameRubyGem(dependency1, dependency2)) {
      +  369  0
                   final File lFile = dependency1.getActualFile();
      +  370  0
                   final File left = lFile.getParentFile();
      +  371  0
                   if (left != null && left.getName().equalsIgnoreCase("specifications")) {
      +  372  0
                       return dependency1;
      +  373   +
                   }
      +  374  0
                   return dependency2;
      +  375  
               }
      -  377  1
               return false;
      -  378   +  376  0
               return null;
      +  377  
           }
      -  379   +  378  
       
      -  380   +  379  
           /**
      +  380   +
            * This is likely a very broken attempt at determining if the 'left'
       381   -
            * Determines which path is shortest; if path lengths are equal then we use compareTo of the string method to determine if the
      +
            * dependency is the 'core' library in comparison to the 'right' library.
       382   -
            * first path is smaller.
      -  383  
            *
      +  383   +
            * @param left the dependency to test
       384   -
            * @param left the first path to compare
      +
            * @param right the dependency to test against
       385   -
            * @param right the second path to compare
      +
            * @return a boolean indicating whether or not the left dependency should be
       386   -
            * @return <code>true</code> if the leftPath is the shortest; otherwise <code>false</code>
      +
            * considered the "core" version.
       387  
            */
       388   -
           protected boolean firstPathIsShortest(String left, String right) {
      -  389  5
               final String leftPath = left.replace('\\', '/');
      -  390  5
               final String rightPath = right.replace('\\', '/');
      +
           boolean isCore(Dependency left, Dependency right) {
      +  389  4
               final String leftName = left.getFileName().toLowerCase();
      +  390  4
               final String rightName = right.getFileName().toLowerCase();
       391  
       
      -  392  5
               final int leftCount = countChar(leftPath, '/');
      -  393  5
               final int rightCount = countChar(rightPath, '/');
      -  394  5
               if (leftCount == rightCount) {
      -  395  3
                   return leftPath.compareTo(rightPath) <= 0;
      -  396   -
               } else {
      -  397  2
                   return leftCount < rightCount;
      -  398   -
               }
      -  399   -
           }
      -  400   -
       
      +  392   +
               final boolean returnVal;
      +  393  4
               if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
      +  394  4
                       || rightName.contains("core") && !leftName.contains("core")
      +  395  4
                       || rightName.contains("kernel") && !leftName.contains("kernel")) {
      +  396  0
                   returnVal = false;
      +  397  4
               } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
      +  398  2
                       || !rightName.contains("core") && leftName.contains("core")
      +  399  2
                       || !rightName.contains("kernel") && leftName.contains("kernel")) {
      +  400  4
                   returnVal = true;
       401   -
           /**
      +
       //        } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) {
       402   -
            * Counts the number of times the character is present in the string.
      +
       //            returnVal = true;
       403   -
            *
      +
       //        } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) {
       404   -
            * @param string the string to count the characters in
      +
       //            returnVal = false;
       405   -
            * @param c the character to count
      +
               } else {
       406   -
            * @return the number of times the character is present in the string
      +
                   /*
       407   -
            */
      +
                    * considered splitting the names up and comparing the components,
       408   -
           private int countChar(String string, char c) {
      -  409  10
               int count = 0;
      -  410  10
               final int max = string.length();
      -  411  116
               for (int i = 0; i < max; i++) {
      -  412  106
                   if (c == string.charAt(i)) {
      -  413  28
                       count++;
      +
                    * but decided that the file name length should be sufficient as the
      +  409   +
                    * "core" component, if this follows a normal naming protocol should
      +  410   +
                    * be shorter:
      +  411   +
                    * axis2-saaj-1.4.1.jar
      +  412   +
                    * axis2-1.4.1.jar       <-----
      +  413   +
                    * axis2-kernel-1.4.1.jar
       414   -
                   }
      -  415   +
                    */
      +  415  0
                   returnVal = leftName.length() <= rightName.length();
      +  416  
               }
      -  416  10
               return count;
      -  417   -
           }
      -  418   -
       
      +  417  4
               LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName());
      +  418  4
               return returnVal;
       419   -
           /**
      -  420   -
            * Checks if the given file path is contained within a war or ear file.
      -  421   -
            *
      -  422   -
            * @param filePath the file path to check
      -  423   -
            * @return true if the path contains '.war\' or '.ear\'.
      -  424   -
            */
      -  425   -
           private boolean containedInWar(String filePath) {
      -  426  0
               return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*");
      -  427  
           }
      +  420   +
       
      +  421   +
           /**
      +  422   +
            * Compares the SHA1 hashes of two dependencies to determine if they are
      +  423   +
            * equal.
      +  424   +
            *
      +  425   +
            * @param dependency1 a dependency object to compare
      +  426   +
            * @param dependency2 a dependency object to compare
      +  427   +
            * @return true if the sha1 hashes of the two dependencies match; otherwise
       428   +
            * false
      +  429   +
            */
      +  430   +
           private boolean hashesMatch(Dependency dependency1, Dependency dependency2) {
      +  431  4
               if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) {
      +  432  0
                   return false;
      +  433   +
               }
      +  434  4
               return dependency1.getSha1sum().equals(dependency2.getSha1sum());
      +  435   +
           }
      +  436   +
       
      +  437   +
           /**
      +  438   +
            * Determines if the jar is shaded and the created pom.xml identified the
      +  439   +
            * same CPE as the jar - if so, the pom.xml dependency should be removed.
      +  440   +
            *
      +  441   +
            * @param dependency a dependency to check
      +  442   +
            * @param nextDependency another dependency to check
      +  443   +
            * @return true if on of the dependencies is a pom.xml and the identifiers
      +  444   +
            * between the two collections match; otherwise false
      +  445   +
            */
      +  446   +
           private boolean isShadedJar(Dependency dependency, Dependency nextDependency) {
      +  447  4
               final String mainName = dependency.getFileName().toLowerCase();
      +  448  4
               final String nextName = nextDependency.getFileName().toLowerCase();
      +  449  4
               if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) {
      +  450  0
                   return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers());
      +  451  4
               } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) {
      +  452  0
                   return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers());
      +  453   +
               }
      +  454  4
               return false;
      +  455   +
           }
      +  456   +
       
      +  457   +
           /**
      +  458   +
            * Determines which path is shortest; if path lengths are equal then we use
      +  459   +
            * compareTo of the string method to determine if the first path is smaller.
      +  460   +
            *
      +  461   +
            * @param left the first path to compare
      +  462   +
            * @param right the second path to compare
      +  463   +
            * @return <code>true</code> if the leftPath is the shortest; otherwise
      +  464   +
            * <code>false</code>
      +  465   +
            */
      +  466   +
           protected boolean firstPathIsShortest(String left, String right) {
      +  467  10
               final String leftPath = left.replace('\\', '/');
      +  468  10
               final String rightPath = right.replace('\\', '/');
      +  469   +
       
      +  470  10
               final int leftCount = countChar(leftPath, '/');
      +  471  10
               final int rightCount = countChar(rightPath, '/');
      +  472  10
               if (leftCount == rightCount) {
      +  473  6
                   return leftPath.compareTo(rightPath) <= 0;
      +  474   +
               } else {
      +  475  4
                   return leftCount < rightCount;
      +  476   +
               }
      +  477   +
           }
      +  478   +
       
      +  479   +
           /**
      +  480   +
            * Counts the number of times the character is present in the string.
      +  481   +
            *
      +  482   +
            * @param string the string to count the characters in
      +  483   +
            * @param c the character to count
      +  484   +
            * @return the number of times the character is present in the string
      +  485   +
            */
      +  486   +
           private int countChar(String string, char c) {
      +  487  20
               int count = 0;
      +  488  20
               final int max = string.length();
      +  489  232
               for (int i = 0; i < max; i++) {
      +  490  212
                   if (c == string.charAt(i)) {
      +  491  56
                       count++;
      +  492   +
                   }
      +  493   +
               }
      +  494  20
               return count;
      +  495   +
           }
      +  496   +
       
      +  497   +
           /**
      +  498   +
            * Checks if the given file path is contained within a war or ear file.
      +  499   +
            *
      +  500   +
            * @param filePath the file path to check
      +  501   +
            * @return true if the path contains '.war\' or '.ear\'.
      +  502   +
            */
      +  503   +
           private boolean containedInWar(String filePath) {
      +  504  0
               return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*");
      +  505   +
           }
      +  506  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Experimental.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Experimental.html new file mode 100644 index 000000000..9ec7c871f --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Experimental.html @@ -0,0 +1,92 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.analyzer.Experimental
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      Experimental
      N/A
      N/A
      0
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       3  
        *
       4  
        * Licensed under the Apache License, Version 2.0 (the "License");
       5  
        * you may not use this file except in compliance with the License.
       6  
        * You may obtain a copy of the License at
       7  
        *
       8  
        *     http://www.apache.org/licenses/LICENSE-2.0
       9  
        *
       10  
        * Unless required by applicable law or agreed to in writing, software
       11  
        * distributed under the License is distributed on an "AS IS" BASIS,
       12  
        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       13  
        * See the License for the specific language governing permissions and
       14  
        * limitations under the License.
       15  
        *
       16  
        * Copyright (c) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.analyzer;
       19  
       
       20  
       import java.lang.annotation.ElementType;
       21  
       import java.lang.annotation.Retention;
       22  
       import java.lang.annotation.RetentionPolicy;
       23  
       import java.lang.annotation.Target;
       24  
       
       25  
       /**
       26  
        * Annotation used to flag an analyzer as experimental.
       27  
        *
       28  
        * @author jeremy long
       29  
        */
       30  
       @Retention(RetentionPolicy.RUNTIME)
       31  
       @Target(ElementType.TYPE)
       32  
       public @interface Experimental {
       33  
       
       34  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html index a6a2c032f..61c37d06d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html @@ -105,7 +105,7 @@
        * @author Jeremy Long
       44  
        */
      -  45  7
       public class FalsePositiveAnalyzer extends AbstractAnalyzer {
      +  45  18
       public class FalsePositiveAnalyzer extends AbstractAnalyzer {
       46  
       
       47   @@ -114,7 +114,7 @@
            * The Logger.
       49  
            */
      -  50  1
           private static final Logger LOGGER = LoggerFactory.getLogger(FalsePositiveAnalyzer.class);
      +  50  2
           private static final Logger LOGGER = LoggerFactory.getLogger(FalsePositiveAnalyzer.class);
       51  
       
       52   @@ -123,7 +123,7 @@
            * The file filter used to find DLL and EXE.
       54  
            */
      -  55  1
           private static final FileFilter DLL_EXE_FILTER = FileFilterBuilder.newInstance().addExtensions("dll", "exe").build();
      +  55  2
           private static final FileFilter DLL_EXE_FILTER = FileFilterBuilder.newInstance().addExtensions("dll", "exe").build();
       56  
       
       57   @@ -142,7 +142,7 @@
            * The phase that this analyzer is intended to run in.
       64  
            */
      -  65  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
      +  65  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
       66  
       
       67   @@ -159,7 +159,7 @@
           @Override
       73  
           public String getName() {
      -  74  5
               return ANALYZER_NAME;
      +  74  34
               return ANALYZER_NAME;
       75  
           }
       76   @@ -178,7 +178,7 @@
           @Override
       83  
           public AnalysisPhase getAnalysisPhase() {
      -  84  4
               return ANALYSIS_PHASE;
      +  84  10
               return ANALYSIS_PHASE;
       85  
           }
       86   @@ -203,14 +203,14 @@
           @Override
       96  
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      -  97  3
               removeJreEntries(dependency);
      -  98  3
               removeBadMatches(dependency);
      -  99  3
               removeBadSpringMatches(dependency);
      -  100  3
               removeWrongVersionMatches(dependency);
      -  101  3
               removeSpuriousCPE(dependency);
      -  102  3
               removeDuplicativeEntriesFromJar(dependency, engine);
      -  103  3
               addFalseNegativeCPEs(dependency);
      -  104  3
           }
      +  97  10
               removeJreEntries(dependency);
      +  98  10
               removeBadMatches(dependency);
      +  99  10
               removeBadSpringMatches(dependency);
      +  100  10
               removeWrongVersionMatches(dependency);
      +  101  10
               removeSpuriousCPE(dependency);
      +  102  10
               removeDuplicativeEntriesFromJar(dependency, engine);
      +  103  10
               addFalseNegativeCPEs(dependency);
      +  104  10
           }
       105  
       
       106   @@ -225,9 +225,9 @@
            */
       111  
           private void removeBadSpringMatches(Dependency dependency) {
      -  112  3
               String mustContain = null;
      -  113  3
               for (Identifier i : dependency.getIdentifiers()) {
      -  114  3
                   if ("maven".contains(i.getType())) {
      +  112  10
               String mustContain = null;
      +  113  10
               for (Identifier i : dependency.getIdentifiers()) {
      +  114  6
                   if ("maven".contains(i.getType())) {
       115  0
                       if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) {
       116  0
                           final int endPoint = i.getValue().indexOf(':', 19);
       117  0
                           if (endPoint >= 0) {
      @@ -239,8 +239,8 @@
                       }
       122  
                   }
      -  123  3
               }
      -  124  3
               if (mustContain != null) {
      +  123  6
               }
      +  124  10
               if (mustContain != null) {
       125  0
                   final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
       126  0
                   while (itr.hasNext()) {
       127  0
                       final Identifier i = itr.next();
      @@ -256,7 +256,7 @@  135  0
                   }
       136  
               }
      -  137  3
           }
      +  137  10
           }
       138  
       
       139   @@ -299,27 +299,27 @@
           @SuppressWarnings("null")
       158  
           private void removeSpuriousCPE(Dependency dependency) {
      -  159  3
               final List<Identifier> ids = new ArrayList<Identifier>(dependency.getIdentifiers());
      -  160  3
               Collections.sort(ids);
      -  161  3
               final ListIterator<Identifier> mainItr = ids.listIterator();
      -  162  6
               while (mainItr.hasNext()) {
      -  163  3
                   final Identifier currentId = mainItr.next();
      -  164  3
                   final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue());
      -  165  3
                   if (currentCpe == null) {
      +  159  10
               final List<Identifier> ids = new ArrayList<Identifier>(dependency.getIdentifiers());
      +  160  10
               Collections.sort(ids);
      +  161  10
               final ListIterator<Identifier> mainItr = ids.listIterator();
      +  162  16
               while (mainItr.hasNext()) {
      +  163  6
                   final Identifier currentId = mainItr.next();
      +  164  6
                   final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue());
      +  165  6
                   if (currentCpe == null) {
       166  0
                       continue;
       167  
                   }
      -  168  3
                   final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex());
      -  169  6
                   while (subItr.hasNext()) {
      -  170  3
                       final Identifier nextId = subItr.next();
      -  171  3
                       final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue());
      -  172  3
                       if (nextCpe == null) {
      +  168  6
                   final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex());
      +  169  12
                   while (subItr.hasNext()) {
      +  170  6
                       final Identifier nextId = subItr.next();
      +  171  6
                       final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue());
      +  172  6
                       if (nextCpe == null) {
       173  0
                           continue;
       174  
                       }
       175  
                       //TODO fix the version problem below
      -  176  3
                       if (currentCpe.getVendor().equals(nextCpe.getVendor())) {
      +  176  6
                       if (currentCpe.getVendor().equals(nextCpe.getVendor())) {
       177  0
                           if (currentCpe.getProduct().equals(nextCpe.getProduct())) {
       178  
                               // see if one is contained in the other.. remove the contained one from dependency.getIdentifier
      @@ -350,16 +350,16 @@
                           }
       198  
                       }
      -  199  3
                   }
      -  200  3
               }
      -  201  3
           }
      +  199  6
                   }
      +  200  6
               }
      +  201  10
           }
       202  
           /**
       203  
            * Regex to identify core java libraries and a few other commonly misidentified ones.
       204  
            */
      -  205  1
           public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
      +  205  2
           public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
       206  
                   + "java(_platform_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|"
       207   @@ -372,21 +372,21 @@
            * Regex to identify core jsf libraries.
       211  
            */
      -  212  1
           public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)");
      +  212  2
           public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)");
       213  
           /**
       214  
            * Regex to identify core java library files. This is currently incomplete.
       215  
            */
      -  216  1
           public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
      +  216  2
           public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
       217  
           /**
       218  
            * Regex to identify core jsf java library files. This is currently incomplete.
       219  
            */
      -  220  1
           public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$");
      +  220  2
           public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$");
       221  
       
       222   @@ -401,24 +401,24 @@
            */
       227  
           private void removeJreEntries(Dependency dependency) {
      -  228  3
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      -  229  3
               final Iterator<Identifier> itr = identifiers.iterator();
      -  230  7
               while (itr.hasNext()) {
      -  231  4
                   final Identifier i = itr.next();
      -  232  4
                   final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
      -  233  4
                   final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
      -  234  4
                   if (coreCPE.matches() && !coreFiles.matches()) {
      +  228  10
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      +  229  10
               final Iterator<Identifier> itr = identifiers.iterator();
      +  230  18
               while (itr.hasNext()) {
      +  231  8
                   final Identifier i = itr.next();
      +  232  8
                   final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
      +  233  8
                   final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
      +  234  8
                   if (coreCPE.matches() && !coreFiles.matches()) {
       235  0
                       itr.remove();
       236  
                   }
      -  237  4
                   final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
      -  238  4
                   final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
      -  239  4
                   if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
      +  237  8
                   final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
      +  238  8
                   final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
      +  239  8
                   if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
       240  0
                       itr.remove();
       241  
                   }
      -  242  4
               }
      -  243  3
           }
      +  242  8
               }
      +  243  10
           }
       244  
       
       245   @@ -437,19 +437,19 @@
            */
       252  
           private VulnerableSoftware parseCpe(String type, String value) {
      -  253  6
               if (!"cpe".equals(type)) {
      +  253  12
               if (!"cpe".equals(type)) {
       254  0
                   return null;
       255  
               }
      -  256  6
               final VulnerableSoftware cpe = new VulnerableSoftware();
      +  256  12
               final VulnerableSoftware cpe = new VulnerableSoftware();
       257  
               try {
      -  258  6
                   cpe.parseName(value);
      +  258  12
                   cpe.parseName(value);
       259  0
               } catch (UnsupportedEncodingException ex) {
       260  0
                   LOGGER.trace("", ex);
       261  0
                   return null;
      -  262  6
               }
      -  263  6
               return cpe;
      +  262  12
               }
      +  263  12
               return cpe;
       264  
           }
       265   @@ -468,8 +468,8 @@
            */
       272  
           private void removeBadMatches(Dependency dependency) {
      -  273  3
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      -  274  3
               final Iterator<Identifier> itr = identifiers.iterator();
      +  273  10
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      +  274  10
               final Iterator<Identifier> itr = identifiers.iterator();
       275  
       
       276   @@ -486,21 +486,21 @@
               //Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
       282  
               //Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
      -  283  7
               while (itr.hasNext()) {
      -  284  4
                   final Identifier i = itr.next();
      +  283  18
               while (itr.hasNext()) {
      +  284  8
                   final Identifier i = itr.next();
       285  
                   //TODO move this startsWith expression to the base suppression file
      -  286  4
                   if ("cpe".equals(i.getType())) {
      -  287  4
                       if ((i.getValue().matches(".*c\\+\\+.*")
      -  288  4
                               || i.getValue().startsWith("cpe:/a:file:file")
      -  289  3
                               || i.getValue().startsWith("cpe:/a:mozilla:mozilla")
      -  290  3
                               || i.getValue().startsWith("cpe:/a:cvs:cvs")
      -  291  3
                               || i.getValue().startsWith("cpe:/a:ftp:ftp")
      -  292  3
                               || i.getValue().startsWith("cpe:/a:tcp:tcp")
      -  293  3
                               || i.getValue().startsWith("cpe:/a:ssh:ssh")
      -  294  3
                               || i.getValue().startsWith("cpe:/a:lookup:lookup"))
      -  295  1
                               && (dependency.getFileName().toLowerCase().endsWith(".jar")
      -  296  1
                               || dependency.getFileName().toLowerCase().endsWith("pom.xml")
      +  286  8
                   if ("cpe".equals(i.getType())) {
      +  287  8
                       if ((i.getValue().matches(".*c\\+\\+.*")
      +  288  8
                               || i.getValue().startsWith("cpe:/a:file:file")
      +  289  6
                               || i.getValue().startsWith("cpe:/a:mozilla:mozilla")
      +  290  6
                               || i.getValue().startsWith("cpe:/a:cvs:cvs")
      +  291  6
                               || i.getValue().startsWith("cpe:/a:ftp:ftp")
      +  292  6
                               || i.getValue().startsWith("cpe:/a:tcp:tcp")
      +  293  6
                               || i.getValue().startsWith("cpe:/a:ssh:ssh")
      +  294  6
                               || i.getValue().startsWith("cpe:/a:lookup:lookup"))
      +  295  2
                               && (dependency.getFileName().toLowerCase().endsWith(".jar")
      +  296  2
                               || dependency.getFileName().toLowerCase().endsWith("pom.xml")
       297  0
                               || dependency.getFileName().toLowerCase().endsWith(".dll")
       298  0
                               || dependency.getFileName().toLowerCase().endsWith(".exe")
       299  0
                               || dependency.getFileName().toLowerCase().endsWith(".nuspec")
      @@ -512,41 +512,41 @@  305  0
                               || dependency.getFileName().toLowerCase().endsWith(".tgz")
       306  0
                               || dependency.getFileName().toLowerCase().endsWith(".ear")
       307  0
                               || dependency.getFileName().toLowerCase().endsWith(".war"))) {
      -  308  1
                           itr.remove();
      -  309  3
                       } else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
      -  310  3
                               || i.getValue().startsWith("cpe:/a:prototypejs:prototype")
      -  311  3
                               || i.getValue().startsWith("cpe:/a:yahoo:yui"))
      +  308  2
                           itr.remove();
      +  309  6
                       } else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
      +  310  6
                               || i.getValue().startsWith("cpe:/a:prototypejs:prototype")
      +  311  6
                               || i.getValue().startsWith("cpe:/a:yahoo:yui"))
       312  0
                               && (dependency.getFileName().toLowerCase().endsWith(".jar")
       313  0
                               || dependency.getFileName().toLowerCase().endsWith("pom.xml")
       314  0
                               || dependency.getFileName().toLowerCase().endsWith(".dll")
       315  0
                               || dependency.getFileName().toLowerCase().endsWith(".exe"))) {
       316  0
                           itr.remove();
      -  317  3
                       } else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
      -  318  3
                               || i.getValue().startsWith("cpe:/a:microsoft:word")
      -  319  3
                               || i.getValue().startsWith("cpe:/a:microsoft:visio")
      -  320  3
                               || i.getValue().startsWith("cpe:/a:microsoft:powerpoint")
      -  321  3
                               || i.getValue().startsWith("cpe:/a:microsoft:office")
      -  322  3
                               || i.getValue().startsWith("cpe:/a:core_ftp:core_ftp"))
      +  317  6
                       } else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
      +  318  6
                               || i.getValue().startsWith("cpe:/a:microsoft:word")
      +  319  6
                               || i.getValue().startsWith("cpe:/a:microsoft:visio")
      +  320  6
                               || i.getValue().startsWith("cpe:/a:microsoft:powerpoint")
      +  321  6
                               || i.getValue().startsWith("cpe:/a:microsoft:office")
      +  322  6
                               || i.getValue().startsWith("cpe:/a:core_ftp:core_ftp"))
       323  0
                               && (dependency.getFileName().toLowerCase().endsWith(".jar")
       324  0
                               || dependency.getFileName().toLowerCase().endsWith(".ear")
       325  0
                               || dependency.getFileName().toLowerCase().endsWith(".war")
       326  0
                               || dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
       327  0
                           itr.remove();
      -  328  3
                       } else if (i.getValue().startsWith("cpe:/a:apache:maven")
      +  328  6
                       } else if (i.getValue().startsWith("cpe:/a:apache:maven")
       329  0
                               && !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
       330  0
                           itr.remove();
      -  331  3
                       } else if (i.getValue().startsWith("cpe:/a:m-core:m-core")
      +  331  6
                       } else if (i.getValue().startsWith("cpe:/a:m-core:m-core")
       332  0
                               && !dependency.getEvidenceUsed().containsUsedString("m-core")) {
       333  0
                           itr.remove();
      -  334  3
                       } else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
      +  334  6
                       } else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
       335  0
                               && !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) {
       336  0
                           itr.remove();
       337  
                       }
       338  
                   }
      -  339  4
               }
      -  340  3
           }
      +  339  8
               }
      +  340  10
           }
       341  
       
       342   @@ -561,12 +561,12 @@
            */
       347  
           private void removeWrongVersionMatches(Dependency dependency) {
      -  348  3
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      -  349  3
               final Iterator<Identifier> itr = identifiers.iterator();
      +  348  10
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      +  349  10
               final Iterator<Identifier> itr = identifiers.iterator();
       350  
       
      -  351  3
               final String fileName = dependency.getFileName();
      -  352  3
               if (fileName != null && fileName.contains("axis2")) {
      +  351  10
               final String fileName = dependency.getFileName();
      +  352  10
               if (fileName != null && fileName.contains("axis2")) {
       353  0
                   while (itr.hasNext()) {
       354  0
                       final Identifier i = itr.next();
       355  0
                       if ("cpe".equals(i.getType())) {
      @@ -578,7 +578,7 @@  360  
                       }
       361  0
                   }
      -  362  3
               } else if (fileName != null && fileName.contains("axis")) {
      +  362  10
               } else if (fileName != null && fileName.contains("axis")) {
       363  0
                   while (itr.hasNext()) {
       364  0
                       final Identifier i = itr.next();
       365  0
                       if ("cpe".equals(i.getType())) {
      @@ -592,7 +592,7 @@  371  0
                   }
       372  
               }
      -  373  3
           }
      +  373  10
           }
       374  
       
       375   @@ -611,12 +611,12 @@
           private void addFalseNegativeCPEs(Dependency dependency) {
       382  
               //TODO move this to the hint analyzer
      -  383  3
               for (final Identifier identifier : dependency.getIdentifiers()) {
      -  384  3
                   if ("cpe".equals(identifier.getType()) && identifier.getValue() != null
      -  385  3
                           && (identifier.getValue().startsWith("cpe:/a:oracle:opensso:")
      -  386  3
                           || identifier.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
      -  387  3
                           || identifier.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
      -  388  3
                           || identifier.getValue().startsWith("cpe:/a:sun:opensso:"))) {
      +  383  10
               for (final Identifier identifier : dependency.getIdentifiers()) {
      +  384  6
                   if ("cpe".equals(identifier.getType()) && identifier.getValue() != null
      +  385  6
                           && (identifier.getValue().startsWith("cpe:/a:oracle:opensso:")
      +  386  6
                           || identifier.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
      +  387  6
                           || identifier.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
      +  388  6
                           || identifier.getValue().startsWith("cpe:/a:sun:opensso:"))) {
       389  0
                       final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", identifier.getValue().substring(22));
       390  0
                       final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", identifier.getValue().substring(22));
       391  0
                       final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", identifier.getValue().substring(22));
      @@ -644,8 +644,8 @@  408  0
                       }
       409  
                   }
      -  410  3
               }
      -  411  3
           }
      +  410  6
               }
      +  411  10
           }
       412  
       
       413   @@ -664,10 +664,10 @@
            */
       420  
           private void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) {
      -  421  3
               if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
      -  422  2
                       || DLL_EXE_FILTER.accept(dependency.getActualFile())) {
      -  423  1
                   String parentPath = dependency.getFilePath().toLowerCase();
      -  424  1
                   if (parentPath.contains(".jar")) {
      +  421  10
               if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
      +  422  8
                       || DLL_EXE_FILTER.accept(dependency.getActualFile())) {
      +  423  2
                   String parentPath = dependency.getFilePath().toLowerCase();
      +  424  2
                   if (parentPath.contains(".jar")) {
       425  0
                       parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4);
       426  0
                       final Dependency parent = findDependency(parentPath, engine.getDependencies());
       427  0
                       if (parent != null) {
      @@ -700,7 +700,7 @@
       
       448  
               }
      -  449  3
           }
      +  449  10
           }
       450  
       
       451   @@ -761,6 +761,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html index a66884919..12f39ea55 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      FileNameAnalyzer
      77%
      17/22
      40%
      4/10
      2.667
      FileNameAnalyzer
      89%
      17/19
      62%
      5/8
      2.333
       
      @@ -89,7 +89,7 @@
        * @author Jeremy Long
       36  
        */
      -  37  9
       public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
      +  37  22
       public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
       38  
       
       39   @@ -108,7 +108,7 @@
            * The phase that this analyzer is intended to run in.
       46  
            */
      -  47  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  47  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       48  
       
       49   @@ -125,7 +125,7 @@
           @Override
       55  
           public String getName() {
      -  56  5
               return ANALYZER_NAME;
      +  56  34
               return ANALYZER_NAME;
       57  
           }
       58   @@ -144,7 +144,7 @@
           @Override
       65  
           public AnalysisPhase getAnalysisPhase() {
      -  66  4
               return ANALYSIS_PHASE;
      +  66  10
               return ANALYSIS_PHASE;
       67  
           }
       68   @@ -152,93 +152,90 @@  69  
       
       70   -
           // Python init files
      -  71  1
           private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[] {
      -  72   -
               "__init__.py",
      -  73   -
               "__init__.pyc",
      -  74   -
               "__init__.pyo"
      -  75   -
           });
      -  76   -
       
      -  77  
           /**
      -  78   -
            * Collects information about the file name.
      -  79   -
            *
      -  80   -
            * @param dependency the dependency to analyze.
      -  81   -
            * @param engine the engine that is scanning the dependencies
      -  82   -
            * @throws AnalysisException is thrown if there is an error reading the JAR file.
      -  83   +  71   +
            * Python init files
      +  72  
            */
      +  73  2
           private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{
      +  74   +
               "__init__.py",
      +  75   +
               "__init__.pyc",
      +  76   +
               "__init__.pyo",
      +  77   +
           });
      +  78   +
       
      +  79   +
           /**
      +  80   +
            * Collects information about the file name.
      +  81   +
            *
      +  82   +
            * @param dependency the dependency to analyze.
      +  83   +
            * @param engine the engine that is scanning the dependencies
       84   -
           @Override
      +
            * @throws AnalysisException is thrown if there is an error reading the JAR
       85   -
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      +
            * file.
       86   -
       
      +
            */
       87   -
               //strip any path information that may get added by ArchiveAnalyzer, etc.
      -  88  4
               final File f = dependency.getActualFile();
      -  89  4
               final String fileName = FilenameUtils.removeExtension(f.getName());
      +
           @Override
      +  88   +
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      +  89   +
       
       90   +
               //strip any path information that may get added by ArchiveAnalyzer, etc.
      +  91  12
               final File f = dependency.getActualFile();
      +  92  12
               final String fileName = FilenameUtils.removeExtension(f.getName());
      +  93  
       
      -  91   -
               //add version evidence
      -  92  4
               final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
      -  93  4
               if (version != null) {
       94   +
               //add version evidence
      +  95  12
               final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
      +  96  12
               if (version != null) {
      +  97  
                   // If the version number is just a number like 2 or 23, reduce the confidence
      -  95   +  98  
                   // a shade. This should hopefully correct for cases like log4j.jar or
      -  96   +  99  
                   // struts2-core.jar
      -  97  4
                   if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
      -  98  0
                       dependency.getVersionEvidence().addEvidence("file", "name",
      -  99  0
                               version.toString(), Confidence.MEDIUM);
      -  100   -
                   } else {
      -  101  8
                       dependency.getVersionEvidence().addEvidence("file", "name",
      -  102  4
                               version.toString(), Confidence.HIGHEST);
      +  100  10
                   if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
      +  101  0
                       dependency.getVersionEvidence().addEvidence("file", "name",
      +  102  0
                               version.toString(), Confidence.MEDIUM);
       103   -
                   }
      -  104  4
                   dependency.getVersionEvidence().addEvidence("file", "name",
      -  105   -
                           fileName, Confidence.MEDIUM);
      +
                   } else {
      +  104  20
                       dependency.getVersionEvidence().addEvidence("file", "version",
      +  105  10
                               version.toString(), Confidence.HIGHEST);
       106   -
               }
      -  107   -
       
      +
                   }
      +  107  10
                   dependency.getVersionEvidence().addEvidence("file", "name",
       108   -
               //add as vendor and product evidence
      -  109  4
               if (fileName.contains("-")) {
      -  110  4
                   dependency.getProductEvidence().addEvidence("file", "name",
      -  111   -
                           fileName, Confidence.HIGHEST);
      -  112  4
                   dependency.getVendorEvidence().addEvidence("file", "name",
      -  113   -
                           fileName, Confidence.HIGHEST);
      -  114  0
               } else if (!IGNORED_FILES.accept(f)) {
      -  115  0
                   dependency.getProductEvidence().addEvidence("file", "name",
      -  116   -
                           fileName, Confidence.HIGH);
      -  117  0
                   dependency.getVendorEvidence().addEvidence("file", "name",
      -  118   -
                           fileName, Confidence.HIGH);
      -  119   +
                           fileName, Confidence.MEDIUM);
      +  109  
               }
      -  120  4
           }
      -  121   +  110   +
       
      +  111  12
               if (!IGNORED_FILES.accept(f)) {
      +  112  12
                   dependency.getProductEvidence().addEvidence("file", "name",
      +  113   +
                           fileName, Confidence.HIGH);
      +  114  12
                   dependency.getVendorEvidence().addEvidence("file", "name",
      +  115   +
                           fileName, Confidence.HIGH);
      +  116   +
               }
      +  117  12
           }
      +  118  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html index 4b0e50821..10de905fc 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html @@ -85,6 +85,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html index a59443980..092a2589f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html @@ -83,7 +83,7 @@
        * @author Jeremy Long
       33  
        */
      -  34  7
       public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
      +  34  18
       public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
       35  
       
       36   @@ -102,7 +102,7 @@
            * The phase that this analyzer is intended to run in.
       43  
            */
      -  44  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS;
      +  44  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS;
       45  
       
       46   @@ -119,7 +119,7 @@
           @Override
       52  
           public String getName() {
      -  53  5
               return ANALYZER_NAME;
      +  53  34
               return ANALYZER_NAME;
       54  
           }
       55   @@ -138,7 +138,7 @@
           @Override
       62  
           public AnalysisPhase getAnalysisPhase() {
      -  63  4
               return ANALYSIS_PHASE;
      +  63  10
               return ANALYSIS_PHASE;
       64  
           }
       65   @@ -165,7 +165,7 @@
           @Override
       76  
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      -  77  2
               final Evidence springTest1 = new Evidence("Manifest",
      +  77  8
               final Evidence springTest1 = new Evidence("Manifest",
       78  
                       "Implementation-Title",
       79   @@ -174,7 +174,7 @@
                       Confidence.HIGH);
       81  
       
      -  82  2
               final Evidence springTest2 = new Evidence("Manifest",
      +  82  8
               final Evidence springTest2 = new Evidence("Manifest",
       83  
                       "Implementation-Title",
       84   @@ -183,7 +183,7 @@
                       Confidence.HIGH);
       86  
       
      -  87  2
               final Evidence springTest3 = new Evidence("Manifest",
      +  87  8
               final Evidence springTest3 = new Evidence("Manifest",
       88  
                       "Implementation-Title",
       89   @@ -192,7 +192,7 @@
                       Confidence.HIGH);
       91  
       
      -  92  2
               final Evidence springTest4 = new Evidence("jar",
      +  92  8
               final Evidence springTest4 = new Evidence("jar",
       93  
                       "package name",
       94   @@ -201,7 +201,7 @@
                       Confidence.LOW);
       96  
       
      -  97  2
               final Evidence springSecurityTest1 = new Evidence("Manifest",
      +  97  8
               final Evidence springSecurityTest1 = new Evidence("Manifest",
       98  
                       "Bundle-Name",
       99   @@ -210,7 +210,7 @@
                       Confidence.MEDIUM);
       101  
       
      -  102  2
               final Evidence springSecurityTest2 = new Evidence("pom",
      +  102  8
               final Evidence springSecurityTest2 = new Evidence("pom",
       103  
                       "artifactid",
       104   @@ -219,7 +219,7 @@
                       Confidence.HIGH);
       106  
       
      -  107  2
               final Evidence symfony = new Evidence("composer.lock",
      +  107  8
               final Evidence symfony = new Evidence("composer.lock",
       108  
                   "vendor",
       109   @@ -228,7 +228,7 @@
                   Confidence.HIGHEST);
       111  
       
      -  112  2
               final Evidence zendframeworkVendor = new Evidence("composer.lock",
      +  112  8
               final Evidence zendframeworkVendor = new Evidence("composer.lock",
       113  
                   "vendor",
       114   @@ -237,7 +237,7 @@
                   Confidence.HIGHEST);
       116  
       
      -  117  2
               final Evidence zendframeworkProduct = new Evidence("composer.lock",
      +  117  8
               final Evidence zendframeworkProduct = new Evidence("composer.lock",
       118  
                   "product",
       119   @@ -248,29 +248,29 @@
       
       122  
               //springsource/vware problem
      -  123  2
               final Set<Evidence> product = dependency.getProductEvidence().getEvidence();
      -  124  2
               final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence();
      +  123  8
               final Set<Evidence> product = dependency.getProductEvidence().getEvidence();
      +  124  8
               final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence();
       125  
       
      -  126  2
               if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3)
      -  127  1
                       || (dependency.getFileName().contains("spring") && product.contains(springTest4))) {
      -  128  1
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH);
      -  129  1
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
      -  130  1
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      -  131  1
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
      +  126  8
               if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3)
      +  127  6
                       || (dependency.getFileName().contains("spring") && product.contains(springTest4))) {
      +  128  2
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH);
      +  129  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
      +  130  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      +  131  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
       132  
               }
       133  
       
      -  134  2
               if (vendor.contains(springTest4)) {
      -  135  1
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH);
      -  136  1
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      -  137  1
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
      +  134  8
               if (vendor.contains(springTest4)) {
      +  135  2
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH);
      +  136  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      +  137  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
       138  
               }
       139  
       
      -  140  2
               if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) {
      +  140  8
               if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) {
       141  0
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_security", Confidence.HIGH);
       142  0
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
       143  0
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      @@ -278,19 +278,19 @@
               }
       145  
       
      -  146  2
               if (vendor.contains(symfony)) {
      +  146  8
               if (vendor.contains(symfony)) {
       147  0
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "sensiolabs", Confidence.HIGHEST);
       148  
               }
       149  
       
      -  150  2
               if (vendor.contains(zendframeworkVendor)) {
      +  150  8
               if (vendor.contains(zendframeworkVendor)) {
       151  0
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "zend", Confidence.HIGHEST);
       152  
               }
       153  
       
      -  154  2
               if (product.contains(zendframeworkProduct)) {
      +  154  8
               if (product.contains(zendframeworkProduct)) {
       155  0
                   dependency.getProductEvidence().addEvidence("hint analyzer", "vendor", "zend_framework", Confidence.HIGHEST);
       156  
               }
      @@ -298,11 +298,11 @@
       
       158  
               //sun/oracle problem
      -  159  2
               final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
      -  160  2
               final List<Evidence> newEntries = new ArrayList<Evidence>();
      -  161  20
               while (itr.hasNext()) {
      -  162  18
                   final Evidence e = itr.next();
      -  163  18
                   if ("sun".equalsIgnoreCase(e.getValue(false))) {
      +  159  8
               final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
      +  160  8
               final List<Evidence> newEntries = new ArrayList<Evidence>();
      +  161  58
               while (itr.hasNext()) {
      +  162  50
                   final Evidence e = itr.next();
      +  163  50
                   if ("sun".equalsIgnoreCase(e.getValue(false))) {
       164  0
                       final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence());
       165  0
                       newEntries.add(newEvidence);
       166  0
                   } else if ("oracle".equalsIgnoreCase(e.getValue(false))) {
      @@ -310,17 +310,17 @@  168  0
                       newEntries.add(newEvidence);
       169  
                   }
      -  170  18
               }
      -  171  2
               for (Evidence e : newEntries) {
      +  170  50
               }
      +  171  8
               for (Evidence e : newEntries) {
       172  0
                   dependency.getVendorEvidence().addEvidence(e);
       173  0
               }
       174  
       
      -  175  2
           }
      +  175  8
           }
       176  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.JarAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.JarAnalyzer.html index f9cb252f9..6dd5491d9 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.JarAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.JarAnalyzer.html @@ -12,8 +12,8 @@
       
      - - + +
      Classes in this File Line Coverage Branch Coverage Complexity
      JarAnalyzer
      65%
      339/520
      51%
      176/342
      7.29
      JarAnalyzer$ClassNameInformation
      80%
      17/21
      80%
      8/10
      7.29
      JarAnalyzer
      66%
      349/522
      56%
      195/346
      7.355
      JarAnalyzer$ClassNameInformation
      80%
      17/21
      80%
      8/10
      7.355
       
      @@ -81,69 +81,69 @@  31  
       import java.util.HashMap;
       32   -
       import java.util.Iterator;
      -  33  
       import java.util.List;
      -  34   +  33  
       import java.util.Map;
      -  35   +  34  
       import java.util.Map.Entry;
      -  36   +  35  
       import java.util.Properties;
      -  37   +  36  
       import java.util.Set;
      -  38   +  37  
       import java.util.StringTokenizer;
      -  39   +  38  
       import java.util.jar.Attributes;
      -  40   +  39  
       import java.util.jar.JarEntry;
      -  41   +  40  
       import java.util.jar.JarFile;
      -  42   +  41  
       import java.util.jar.Manifest;
      -  43   +  42  
       import java.util.regex.Pattern;
      -  44   +  43  
       import java.util.zip.ZipEntry;
      -  45   +  44  
       import org.apache.commons.compress.utils.IOUtils;
      -  46   +  45  
       import org.apache.commons.io.FilenameUtils;
      -  47   +  46  
       import org.jsoup.Jsoup;
      -  48   +  47  
       import org.owasp.dependencycheck.Engine;
      -  49   +  48  
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      -  50   +  49  
       import org.owasp.dependencycheck.dependency.Confidence;
      -  51   +  50  
       import org.owasp.dependencycheck.dependency.Dependency;
      -  52   +  51  
       import org.owasp.dependencycheck.dependency.EvidenceCollection;
      -  53   +  52  
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      -  54   +  53  
       import org.owasp.dependencycheck.xml.pom.License;
      -  55   +  54  
       import org.owasp.dependencycheck.xml.pom.PomUtils;
      -  56   +  55  
       import org.owasp.dependencycheck.xml.pom.Model;
      -  57   +  56  
       import org.owasp.dependencycheck.utils.FileUtils;
      -  58   +  57  
       import org.owasp.dependencycheck.utils.Settings;
      -  59   +  58  
       import org.slf4j.Logger;
      -  60   +  59  
       import org.slf4j.LoggerFactory;
      -  61   +  60  
       
      -  62   +  61  
       /**
      +  62   +
        * Used to load a JAR file and collect information that can be used to determine
       63   -
        * Used to load a JAR file and collect information that can be used to determine the associated CPE.
      +
        * the associated CPE.
       64  
        *
       65   @@ -162,1723 +162,1779 @@
            * The logger.
       72  
            */
      -  73  1
           private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class);
      +  73  2
           private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class);
       74  
           /**
       75   -
            * The count of directories created during analysis. This is used for creating temporary directories.
      +
            * The count of directories created during analysis. This is used for
       76   +
            * creating temporary directories.
      +  77  
            */
      -  77  1
           private static int dirCount = 0;
      -  78   -
           /**
      +  78  2
           private static int dirCount = 0;
       79   -
            * The system independent newline character.
      +
           /**
       80   +
            * The system independent newline character.
      +  81  
            */
      -  81  1
           private static final String NEWLINE = System.getProperty("line.separator");
      -  82   -
           /**
      +  82  2
           private static final String NEWLINE = System.getProperty("line.separator");
       83   -
            * A list of values in the manifest to ignore as they only result in false positives.
      +
           /**
       84   -
            */
      -  85  1
           private static final Set<String> IGNORE_VALUES = newHashSet(
      +
            * A list of values in the manifest to ignore as they only result in false
      +  85   +
            * positives.
       86   -
                   "Sun Java System Application Server");
      -  87   -
           /**
      +
            */
      +  87  2
           private static final Set<String> IGNORE_VALUES = newHashSet(
       88   -
            * A list of elements in the manifest to ignore.
      +
                   "Sun Java System Application Server");
       89   -
            */
      -  90  1
           private static final Set<String> IGNORE_KEYS = newHashSet(
      +
           /**
      +  90   +
            * A list of elements in the manifest to ignore.
       91   -
                   "built-by",
      -  92   -
                   "created-by",
      +
            */
      +  92  2
           private static final Set<String> IGNORE_KEYS = newHashSet(
       93   -
                   "builtby",
      +
                   "built-by",
       94   -
                   "createdby",
      +
                   "created-by",
       95   -
                   "build-jdk",
      +
                   "builtby",
       96   -
                   "buildjdk",
      +
                   "createdby",
       97   -
                   "ant-version",
      +
                   "build-jdk",
       98   -
                   "antversion",
      +
                   "buildjdk",
       99   -
                   "dynamicimportpackage",
      +
                   "ant-version",
       100   -
                   "dynamicimport-package",
      +
                   "antversion",
       101   -
                   "dynamic-importpackage",
      +
                   "dynamicimportpackage",
       102   -
                   "dynamic-import-package",
      +
                   "dynamicimport-package",
       103   -
                   "import-package",
      +
                   "dynamic-importpackage",
       104   -
                   "ignore-package",
      +
                   "dynamic-import-package",
       105   -
                   "export-package",
      +
                   "import-package",
       106   -
                   "importpackage",
      +
                   "ignore-package",
       107   -
                   "ignorepackage",
      +
                   "export-package",
       108   -
                   "exportpackage",
      +
                   "importpackage",
       109   -
                   "sealed",
      +
                   "ignorepackage",
       110   -
                   "manifest-version",
      +
                   "exportpackage",
       111   -
                   "archiver-version",
      +
                   "sealed",
       112   -
                   "manifestversion",
      +
                   "manifest-version",
       113   -
                   "archiverversion",
      +
                   "archiver-version",
       114   -
                   "classpath",
      +
                   "manifestversion",
       115   -
                   "class-path",
      +
                   "archiverversion",
       116   -
                   "tool",
      +
                   "classpath",
       117   -
                   "bundle-manifestversion",
      +
                   "class-path",
       118   -
                   "bundlemanifestversion",
      +
                   "tool",
       119   -
                   "bundle-vendor",
      +
                   "bundle-manifestversion",
       120   -
                   "include-resource",
      +
                   "bundlemanifestversion",
       121   -
                   "embed-dependency",
      +
                   "bundle-vendor",
       122   -
                   "ipojo-components",
      +
                   "include-resource",
       123   -
                   "ipojo-extension",
      +
                   "embed-dependency",
       124   -
                   "eclipse-sourcereferences");
      +
                   "ipojo-components",
       125   -
           /**
      +
                   "ipojo-extension",
       126   -
            * Deprecated Jar manifest attribute, that is, nonetheless, useful for analysis.
      +
                   "eclipse-sourcereferences");
       127   -
            */
      +
           /**
       128   -
           @SuppressWarnings("deprecation")
      -  129  1
           private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID
      -  130  1
                   .toString();
      +
            * Deprecated Jar manifest attribute, that is, nonetheless, useful for
      +  129   +
            * analysis.
      +  130   +
            */
       131   -
           /**
      -  132   -
            * item in some manifest, should be considered medium confidence.
      -  133   -
            */
      +
           @SuppressWarnings("deprecation")
      +  132  2
           private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID
      +  133  2
                   .toString();
       134   -
           private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2
      +
           /**
       135   -
           /**
      +
            * item in some manifest, should be considered medium confidence.
       136   -
            * item in some manifest, should be considered medium confidence.
      +
            */
       137   -
            */
      +
           private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2
       138   -
           private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2
      +
           /**
       139   -
           /**
      -  140  
            * item in some manifest, should be considered medium confidence.
      +  140   +
            */
       141   -
            */
      +
           private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2
       142   -
           private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core
      +
           /**
       143   -
           /**
      +
            * item in some manifest, should be considered medium confidence.
       144   -
            * A pattern to detect HTML within text.
      +
            */
       145   -
            */
      -  146  1
           private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE);
      +
           private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core
      +  146   +
           /**
       147   -
       
      +
            * A pattern to detect HTML within text.
       148   -
           //</editor-fold>
      -  149   -
           /**
      +
            */
      +  149  2
           private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE);
       150   -
            * Constructs a new JarAnalyzer.
      +
       
       151   -
            */
      -  152  8
           public JarAnalyzer() {
      -  153  8
           }
      -  154   -
       
      -  155   -
           //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
      -  156   -
           /**
      -  157   -
            * The name of the analyzer.
      -  158   -
            */
      -  159   -
           private static final String ANALYZER_NAME = "Jar Analyzer";
      -  160   -
           /**
      -  161   -
            * The phase that this analyzer is intended to run in.
      -  162   -
            */
      -  163  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      -  164   -
           /**
      -  165   -
            * The set of file extensions supported by this analyzer.
      -  166   -
            */
      -  167  1
           private static final String[] EXTENSIONS = {"jar", "war"};
      -  168   -
       
      -  169   -
           /**
      -  170   -
            * The file filter used to determine which files this analyzer supports.
      -  171   -
            */
      -  172  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      -  173   -
       
      -  174   -
           /**
      -  175   -
            * Returns the FileFilter.
      -  176   -
            *
      -  177   -
            * @return the FileFilter
      -  178   -
            */
      -  179   -
           @Override
      -  180   -
           protected FileFilter getFileFilter() {
      -  181  855
               return FILTER;
      -  182   -
           }
      -  183   -
       
      -  184   -
           /**
      -  185   -
            * Returns the name of the analyzer.
      -  186   -
            *
      -  187   -
            * @return the name of the analyzer.
      -  188   -
            */
      -  189   -
           @Override
      -  190   -
           public String getName() {
      -  191  5
               return ANALYZER_NAME;
      -  192   -
           }
      -  193   -
       
      -  194   -
           /**
      -  195   -
            * Returns the phase that the analyzer is intended to run in.
      -  196   -
            *
      -  197   -
            * @return the phase that the analyzer is intended to run in.
      -  198   -
            */
      -  199   -
           @Override
      -  200   -
           public AnalysisPhase getAnalysisPhase() {
      -  201  3
               return ANALYSIS_PHASE;
      -  202   -
           }
      -  203  
           //</editor-fold>
      -  204   +  152   +
           /**
      +  153   +
            * Constructs a new JarAnalyzer.
      +  154   +
            */
      +  155  20
           public JarAnalyzer() {
      +  156  20
           }
      +  157  
       
      +  158   +
           //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
      +  159   +
           /**
      +  160   +
            * The name of the analyzer.
      +  161   +
            */
      +  162   +
           private static final String ANALYZER_NAME = "Jar Analyzer";
      +  163   +
           /**
      +  164   +
            * The phase that this analyzer is intended to run in.
      +  165   +
            */
      +  166  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  167   +
           /**
      +  168   +
            * The set of file extensions supported by this analyzer.
      +  169   +
            */
      +  170  2
           private static final String[] EXTENSIONS = {"jar", "war"};
      +  171   +
       
      +  172   +
           /**
      +  173   +
            * The file filter used to determine which files this analyzer supports.
      +  174   +
            */
      +  175  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      +  176   +
       
      +  177   +
           /**
      +  178   +
            * Returns the FileFilter.
      +  179   +
            *
      +  180   +
            * @return the FileFilter
      +  181   +
            */
      +  182   +
           @Override
      +  183   +
           protected FileFilter getFileFilter() {
      +  184  1722
               return FILTER;
      +  185   +
           }
      +  186   +
       
      +  187   +
           /**
      +  188   +
            * Returns the name of the analyzer.
      +  189   +
            *
      +  190   +
            * @return the name of the analyzer.
      +  191   +
            */
      +  192   +
           @Override
      +  193   +
           public String getName() {
      +  194  34
               return ANALYZER_NAME;
      +  195   +
           }
      +  196   +
       
      +  197   +
           /**
      +  198   +
            * Returns the phase that the analyzer is intended to run in.
      +  199   +
            *
      +  200   +
            * @return the phase that the analyzer is intended to run in.
      +  201   +
            */
      +  202   +
           @Override
      +  203   +
           public AnalysisPhase getAnalysisPhase() {
      +  204  8
               return ANALYSIS_PHASE;
       205   -
           /**
      +
           }
       206   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +
           //</editor-fold>
       207   -
            *
      +
       
       208   -
            * @return the analyzer's enabled property setting key
      +
           /**
       209   -
            */
      +
            * Returns the key used in the properties file to reference the analyzer's
       210   -
           @Override
      +
            * enabled property.
       211   -
           protected String getAnalyzerEnabledSettingKey() {
      -  212  8
               return Settings.KEYS.ANALYZER_JAR_ENABLED;
      +
            *
      +  212   +
            * @return the analyzer's enabled property setting key
       213   -
           }
      +
            */
       214   -
       
      -  215   -
           /**
      -  216   -
            * Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE
      -  217   -
            * information.
      -  218   -
            *
      -  219   -
            * @param dependency the dependency to analyze.
      -  220   -
            * @param engine the engine that is scanning the dependencies
      -  221   -
            * @throws AnalysisException is thrown if there is an error reading the JAR file.
      -  222   -
            */
      -  223  
           @Override
      +  215   +
           protected String getAnalyzerEnabledSettingKey() {
      +  216  20
               return Settings.KEYS.ANALYZER_JAR_ENABLED;
      +  217   +
           }
      +  218   +
       
      +  219   +
           /**
      +  220   +
            * Loads a specified JAR file and collects information from the manifest and
      +  221   +
            * checksums to identify the correct CPE information.
      +  222   +
            *
      +  223   +
            * @param dependency the dependency to analyze.
       224   -
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      +
            * @param engine the engine that is scanning the dependencies
       225   +
            * @throws AnalysisException is thrown if there is an error reading the JAR
      +  226   +
            * file.
      +  227   +
            */
      +  228   +
           @Override
      +  229   +
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      +  230  
               try {
      -  226  5
                   final List<ClassNameInformation> classNames = collectClassNames(dependency);
      -  227  5
                   final String fileName = dependency.getFileName().toLowerCase();
      -  228  5
                   if (classNames.isEmpty()
      -  229  0
                           && (fileName.endsWith("-sources.jar")
      -  230  0
                           || fileName.endsWith("-javadoc.jar")
      -  231  0
                           || fileName.endsWith("-src.jar")
      -  232  0
                           || fileName.endsWith("-doc.jar"))) {
      -  233  0
                       engine.getDependencies().remove(dependency);
      -  234   +  231  12
                   final List<ClassNameInformation> classNames = collectClassNames(dependency);
      +  232  12
                   final String fileName = dependency.getFileName().toLowerCase();
      +  233  12
                   if (classNames.isEmpty()
      +  234  2
                           && (fileName.endsWith("-sources.jar")
      +  235  2
                           || fileName.endsWith("-javadoc.jar")
      +  236  2
                           || fileName.endsWith("-src.jar")
      +  237  2
                           || fileName.endsWith("-doc.jar"))) {
      +  238  0
                       engine.getDependencies().remove(dependency);
      +  239  
                   }
      -  235  5
                   final boolean hasManifest = parseManifest(dependency, classNames);
      -  236  5
                   final boolean hasPOM = analyzePOM(dependency, classNames, engine);
      -  237  5
                   final boolean addPackagesAsEvidence = !(hasManifest && hasPOM);
      -  238  5
                   analyzePackageNames(classNames, dependency, addPackagesAsEvidence);
      -  239  0
               } catch (IOException ex) {
      -  240  0
                   throw new AnalysisException("Exception occurred reading the JAR file.", ex);
      -  241  5
               }
      -  242  5
           }
      -  243   -
       
      -  244   -
           /**
      -  245   -
            * Attempts to find a pom.xml within the JAR file. If found it extracts information and adds it to the evidence. This will
      -  246   -
            * attempt to interpolate the strings contained within the pom.properties if one exists.
      -  247   -
            *
      +  240  12
                   final boolean hasManifest = parseManifest(dependency, classNames);
      +  241  12
                   final boolean hasPOM = analyzePOM(dependency, classNames, engine);
      +  242  12
                   final boolean addPackagesAsEvidence = !(hasManifest && hasPOM);
      +  243  12
                   analyzePackageNames(classNames, dependency, addPackagesAsEvidence);
      +  244  0
               } catch (IOException ex) {
      +  245  0
                   throw new AnalysisException("Exception occurred reading the JAR file.", ex);
      +  246  12
               }
      +  247  12
           }
       248   -
            * @param dependency the dependency being analyzed
      +
       
       249   -
            * @param classes a collection of class name information
      +
           /**
       250   -
            * @param engine the analysis engine, used to add additional dependencies
      +
            * Attempts to find a pom.xml within the JAR file. If found it extracts
       251   -
            * @throws AnalysisException is thrown if there is an exception parsing the pom
      +
            * information and adds it to the evidence. This will attempt to interpolate
       252   -
            * @return whether or not evidence was added to the dependency
      +
            * the strings contained within the pom.properties if one exists.
       253   -
            */
      +
            *
       254   -
           protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException {
      -  255  5
               boolean foundSomething = false;
      -  256   -
               final JarFile jar;
      -  257   -
               try {
      -  258  5
                   jar = new JarFile(dependency.getActualFilePath());
      -  259  0
               } catch (IOException ex) {
      -  260  0
                   LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath());
      -  261  0
                   LOGGER.trace("", ex);
      -  262  0
                   return false;
      -  263  5
               }
      -  264   -
               List<String> pomEntries;
      -  265   -
               try {
      -  266  5
                   pomEntries = retrievePomListing(jar);
      -  267  0
               } catch (IOException ex) {
      -  268  0
                   LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath());
      -  269  0
                   LOGGER.trace("", ex);
      -  270  0
                   return false;
      -  271  5
               }
      -  272  5
               File externalPom = null;
      -  273  5
               if (pomEntries.isEmpty()) {
      -  274  4
                   final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom";
      -  275  4
                   externalPom = new File(pomPath);
      -  276  4
                   if (externalPom.isFile()) {
      -  277  0
                       pomEntries.add(pomPath);
      -  278   -
                   } else {
      -  279  4
                       return false;
      -  280   -
                   }
      -  281   -
               }
      -  282  1
               for (String path : pomEntries) {
      -  283  1
                   LOGGER.debug("Reading pom entry: {}", path);
      -  284  1
                   Properties pomProperties = null;
      -  285   -
                   try {
      -  286  1
                       if (externalPom == null) {
      -  287  1
                           pomProperties = retrievePomProperties(path, jar);
      -  288   -
                       }
      -  289  0
                   } catch (IOException ex) {
      -  290  0
                       LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex);
      -  291  1
                   }
      -  292  1
                   Model pom = null;
      -  293   -
                   try {
      -  294  1
                       if (pomEntries.size() > 1) {
      -  295   -
                           //extract POM to its own directory and add it as its own dependency
      -  296  0
                           final Dependency newDependency = new Dependency();
      -  297  0
                           pom = extractPom(path, jar, newDependency);
      -  298   -
       
      -  299  0
                           final String displayPath = String.format("%s%s%s",
      -  300  0
                                   dependency.getFilePath(),
      -  301   -
                                   File.separator,
      -  302   -
                                   path);
      -  303  0
                           final String displayName = String.format("%s%s%s",
      -  304  0
                                   dependency.getFileName(),
      -  305   -
                                   File.separator,
      -  306   -
                                   path);
      -  307   -
       
      -  308  0
                           newDependency.setFileName(displayName);
      -  309  0
                           newDependency.setFilePath(displayPath);
      -  310  0
                           pom.processProperties(pomProperties);
      -  311  0
                           setPomEvidence(newDependency, pom, null);
      -  312  0
                           engine.getDependencies().add(newDependency);
      -  313  0
                           Collections.sort(engine.getDependencies());
      -  314  0
                       } else {
      -  315  1
                           if (externalPom == null) {
      -  316  1
                               pom = PomUtils.readPom(path, jar);
      -  317   -
                           } else {
      -  318  0
                               pom = PomUtils.readPom(externalPom);
      -  319   -
                           }
      -  320  1
                           pom.processProperties(pomProperties);
      -  321  1
                           foundSomething |= setPomEvidence(dependency, pom, classes);
      -  322   -
                       }
      -  323  0
                   } catch (AnalysisException ex) {
      -  324  0
                       LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath());
      -  325  0
                       LOGGER.trace("", ex);
      -  326  1
                   }
      -  327  1
               }
      -  328  1
               return foundSomething;
      -  329   -
           }
      -  330   -
       
      -  331   -
           /**
      -  332   -
            * Given a path to a pom.xml within a JarFile, this method attempts to load a sibling pom.properties if one exists.
      -  333   -
            *
      -  334   -
            * @param path the path to the pom.xml within the JarFile
      -  335   -
            * @param jar the JarFile to load the pom.properties from
      -  336   -
            * @return a Properties object or null if no pom.properties was found
      -  337   -
            * @throws IOException thrown if there is an exception reading the pom.properties
      -  338   -
            */
      -  339   -
           private Properties retrievePomProperties(String path, final JarFile jar) throws IOException {
      -  340  1
               Properties pomProperties = null;
      -  341  1
               final String propPath = path.substring(0, path.length() - 7) + "pom.properies";
      -  342  1
               final ZipEntry propEntry = jar.getEntry(propPath);
      -  343  1
               if (propEntry != null) {
      -  344  0
                   Reader reader = null;
      -  345   -
                   try {
      -  346  0
                       reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8");
      -  347  0
                       pomProperties = new Properties();
      -  348  0
                       pomProperties.load(reader);
      -  349  0
                       LOGGER.debug("Read pom.properties: {}", propPath);
      -  350   -
                   } finally {
      -  351  0
                       if (reader != null) {
      -  352   -
                           try {
      -  353  0
                               reader.close();
      -  354  0
                           } catch (IOException ex) {
      -  355  0
                               LOGGER.trace("close error", ex);
      -  356  0
                           }
      -  357   -
                       }
      -  358   -
                   }
      -  359   -
               }
      -  360  1
               return pomProperties;
      -  361   -
           }
      -  362   -
       
      -  363   -
           /**
      -  364   -
            * Searches a JarFile for pom.xml entries and returns a listing of these entries.
      -  365   -
            *
      -  366   -
            * @param jar the JarFile to search
      -  367   -
            * @return a list of pom.xml entries
      -  368   -
            * @throws IOException thrown if there is an exception reading a JarEntry
      -  369   -
            */
      -  370   -
           private List<String> retrievePomListing(final JarFile jar) throws IOException {
      -  371  5
               final List<String> pomEntries = new ArrayList<String>();
      -  372  5
               final Enumeration<JarEntry> entries = jar.entries();
      -  373  1848
               while (entries.hasMoreElements()) {
      -  374  1843
                   final JarEntry entry = entries.nextElement();
      -  375  1843
                   final String entryName = (new File(entry.getName())).getName().toLowerCase();
      -  376  1843
                   if (!entry.isDirectory() && "pom.xml".equals(entryName)) {
      -  377  1
                       LOGGER.trace("POM Entry found: {}", entry.getName());
      -  378  1
                       pomEntries.add(entry.getName());
      -  379   -
                   }
      -  380  1843
               }
      -  381  5
               return pomEntries;
      -  382   -
           }
      -  383   -
       
      -  384   -
           /**
      -  385   -
            * Retrieves the specified POM from a jar file and converts it to a Model.
      -  386   -
            *
      -  387   -
            * @param path the path to the pom.xml file within the jar file
      -  388   -
            * @param jar the jar file to extract the pom from
      -  389  
            * @param dependency the dependency being analyzed
      -  390   -
            * @return returns the POM object
      -  391   -
            * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
      +  255   +
            * @param classes a collection of class name information
      +  256   +
            * @param engine the analysis engine, used to add additional dependencies
      +  257   +
            * @throws AnalysisException is thrown if there is an exception parsing the
      +  258   +
            * pom
      +  259   +
            * @return whether or not evidence was added to the dependency
      +  260   +
            */
      +  261   +
           protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException {
      +  262  12
               boolean foundSomething = false;
      +  263   +
               final JarFile jar;
      +  264   +
               try {
      +  265  12
                   jar = new JarFile(dependency.getActualFilePath());
      +  266  0
               } catch (IOException ex) {
      +  267  0
                   LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath());
      +  268  0
                   LOGGER.trace("", ex);
      +  269  0
                   return false;
      +  270  12
               }
      +  271   +
               List<String> pomEntries;
      +  272   +
               try {
      +  273  12
                   pomEntries = retrievePomListing(jar);
      +  274  0
               } catch (IOException ex) {
      +  275  0
                   LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath());
      +  276  0
                   LOGGER.trace("", ex);
      +  277  0
                   return false;
      +  278  12
               }
      +  279  12
               File externalPom = null;
      +  280  12
               if (pomEntries.isEmpty()) {
      +  281  8
                   final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom";
      +  282  8
                   externalPom = new File(pomPath);
      +  283  8
                   if (externalPom.isFile()) {
      +  284  0
                       pomEntries.add(pomPath);
      +  285   +
                   } else {
      +  286  8
                       return false;
      +  287   +
                   }
      +  288   +
               }
      +  289  4
               for (String path : pomEntries) {
      +  290  4
                   LOGGER.debug("Reading pom entry: {}", path);
      +  291  4
                   Properties pomProperties = null;
      +  292   +
                   try {
      +  293  4
                       if (externalPom == null) {
      +  294  4
                           pomProperties = retrievePomProperties(path, jar);
      +  295   +
                       }
      +  296  0
                   } catch (IOException ex) {
      +  297  0
                       LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex);
      +  298  4
                   }
      +  299  4
                   Model pom = null;
      +  300   +
                   try {
      +  301  4
                       if (pomEntries.size() > 1) {
      +  302   +
                           //extract POM to its own directory and add it as its own dependency
      +  303  0
                           final Dependency newDependency = new Dependency();
      +  304  0
                           pom = extractPom(path, jar, newDependency);
      +  305   +
       
      +  306  0
                           final String displayPath = String.format("%s%s%s",
      +  307  0
                                   dependency.getFilePath(),
      +  308   +
                                   File.separator,
      +  309   +
                                   path);
      +  310  0
                           final String displayName = String.format("%s%s%s",
      +  311  0
                                   dependency.getFileName(),
      +  312   +
                                   File.separator,
      +  313   +
                                   path);
      +  314   +
       
      +  315  0
                           newDependency.setFileName(displayName);
      +  316  0
                           newDependency.setFilePath(displayPath);
      +  317  0
                           pom.processProperties(pomProperties);
      +  318  0
                           setPomEvidence(newDependency, pom, null);
      +  319  0
                           engine.getDependencies().add(newDependency);
      +  320  0
                           Collections.sort(engine.getDependencies());
      +  321  0
                       } else {
      +  322  4
                           if (externalPom == null) {
      +  323  4
                               pom = PomUtils.readPom(path, jar);
      +  324   +
                           } else {
      +  325  0
                               pom = PomUtils.readPom(externalPom);
      +  326   +
                           }
      +  327  4
                           pom.processProperties(pomProperties);
      +  328  4
                           foundSomething |= setPomEvidence(dependency, pom, classes);
      +  329   +
                       }
      +  330  0
                   } catch (AnalysisException ex) {
      +  331  0
                       LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath());
      +  332  0
                       LOGGER.trace("", ex);
      +  333  4
                   }
      +  334  4
               }
      +  335  4
               return foundSomething;
      +  336   +
           }
      +  337   +
       
      +  338   +
           /**
      +  339   +
            * Given a path to a pom.xml within a JarFile, this method attempts to load
      +  340   +
            * a sibling pom.properties if one exists.
      +  341   +
            *
      +  342   +
            * @param path the path to the pom.xml within the JarFile
      +  343   +
            * @param jar the JarFile to load the pom.properties from
      +  344   +
            * @return a Properties object or null if no pom.properties was found
      +  345   +
            * @throws IOException thrown if there is an exception reading the
      +  346   +
            * pom.properties
      +  347   +
            */
      +  348   +
           private Properties retrievePomProperties(String path, final JarFile jar) throws IOException {
      +  349  4
               Properties pomProperties = null;
      +  350  4
               final String propPath = path.substring(0, path.length() - 7) + "pom.properies";
      +  351  4
               final ZipEntry propEntry = jar.getEntry(propPath);
      +  352  4
               if (propEntry != null) {
      +  353  0
                   Reader reader = null;
      +  354   +
                   try {
      +  355  0
                       reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8");
      +  356  0
                       pomProperties = new Properties();
      +  357  0
                       pomProperties.load(reader);
      +  358  0
                       LOGGER.debug("Read pom.properties: {}", propPath);
      +  359   +
                   } finally {
      +  360  0
                       if (reader != null) {
      +  361   +
                           try {
      +  362  0
                               reader.close();
      +  363  0
                           } catch (IOException ex) {
      +  364  0
                               LOGGER.trace("close error", ex);
      +  365  0
                           }
      +  366   +
                       }
      +  367   +
                   }
      +  368   +
               }
      +  369  4
               return pomProperties;
      +  370   +
           }
      +  371   +
       
      +  372   +
           /**
      +  373   +
            * Searches a JarFile for pom.xml entries and returns a listing of these
      +  374   +
            * entries.
      +  375   +
            *
      +  376   +
            * @param jar the JarFile to search
      +  377   +
            * @return a list of pom.xml entries
      +  378   +
            * @throws IOException thrown if there is an exception reading a JarEntry
      +  379   +
            */
      +  380   +
           private List<String> retrievePomListing(final JarFile jar) throws IOException {
      +  381  12
               final List<String> pomEntries = new ArrayList<String>();
      +  382  12
               final Enumeration<JarEntry> entries = jar.entries();
      +  383  3704
               while (entries.hasMoreElements()) {
      +  384  3692
                   final JarEntry entry = entries.nextElement();
      +  385  3692
                   final String entryName = (new File(entry.getName())).getName().toLowerCase();
      +  386  3692
                   if (!entry.isDirectory() && "pom.xml".equals(entryName)) {
      +  387  4
                       LOGGER.trace("POM Entry found: {}", entry.getName());
      +  388  4
                       pomEntries.add(entry.getName());
      +  389   +
                   }
      +  390  3692
               }
      +  391  12
               return pomEntries;
       392   -
            * {@link org.owasp.dependencycheck.xml.pom.Model} object
      +
           }
       393   -
            */
      +
       
       394   -
           private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException {
      -  395  0
               InputStream input = null;
      -  396  0
               FileOutputStream fos = null;
      -  397  0
               final File tmpDir = getNextTempDirectory();
      -  398  0
               final File file = new File(tmpDir, "pom.xml");
      +
           /**
      +  395   +
            * Retrieves the specified POM from a jar file and converts it to a Model.
      +  396   +
            *
      +  397   +
            * @param path the path to the pom.xml file within the jar file
      +  398   +
            * @param jar the jar file to extract the pom from
       399   +
            * @param dependency the dependency being analyzed
      +  400   +
            * @return returns the POM object
      +  401   +
            * @throws AnalysisException is thrown if there is an exception extracting
      +  402   +
            * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object
      +  403   +
            */
      +  404   +
           private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException {
      +  405  0
               InputStream input = null;
      +  406  0
               FileOutputStream fos = null;
      +  407  0
               final File tmpDir = getNextTempDirectory();
      +  408  0
               final File file = new File(tmpDir, "pom.xml");
      +  409  
               try {
      -  400  0
                   final ZipEntry entry = jar.getEntry(path);
      -  401  0
                   input = jar.getInputStream(entry);
      -  402  0
                   fos = new FileOutputStream(file);
      -  403  0
                   IOUtils.copy(input, fos);
      -  404  0
                   dependency.setActualFilePath(file.getAbsolutePath());
      -  405  0
               } catch (IOException ex) {
      -  406  0
                   LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath());
      -  407  0
                   LOGGER.error("", ex);
      -  408   -
               } finally {
      -  409  0
                   closeStream(fos);
      -  410  0
                   closeStream(input);
      -  411  0
               }
      -  412  0
               return PomUtils.readPom(file);
      -  413   -
           }
      -  414   -
       
      -  415   -
           /**
      -  416   -
            * Silently closes an input stream ignoring errors.
      -  417   -
            *
      +  410  0
                   final ZipEntry entry = jar.getEntry(path);
      +  411  0
                   input = jar.getInputStream(entry);
      +  412  0
                   fos = new FileOutputStream(file);
      +  413  0
                   IOUtils.copy(input, fos);
      +  414  0
                   dependency.setActualFilePath(file.getAbsolutePath());
      +  415  0
               } catch (IOException ex) {
      +  416  0
                   LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath());
      +  417  0
                   LOGGER.error("", ex);
       418   -
            * @param stream an input stream to close
      -  419   -
            */
      -  420   -
           private void closeStream(InputStream stream) {
      -  421  0
               if (stream != null) {
      -  422   -
                   try {
      -  423  0
                       stream.close();
      -  424  0
                   } catch (IOException ex) {
      -  425  0
                       LOGGER.trace("", ex);
      -  426  0
                   }
      -  427   -
               }
      -  428  0
           }
      -  429   -
       
      -  430   -
           /**
      -  431   -
            * Silently closes an output stream ignoring errors.
      -  432   -
            *
      -  433   -
            * @param stream an output stream to close
      -  434   -
            */
      -  435   -
           private void closeStream(OutputStream stream) {
      -  436  0
               if (stream != null) {
      -  437   -
                   try {
      -  438  0
                       stream.close();
      -  439  0
                   } catch (IOException ex) {
      -  440  0
                       LOGGER.trace("", ex);
      -  441  0
                   }
      -  442   -
               }
      -  443  0
           }
      -  444   -
       
      -  445   -
           /**
      -  446   -
            * Sets evidence from the pom on the supplied dependency.
      -  447   -
            *
      -  448   -
            * @param dependency the dependency to set data on
      -  449   -
            * @param pom the information from the pom
      -  450   -
            * @param classes a collection of ClassNameInformation - containing data about the fully qualified class names within the JAR
      -  451   -
            * file being analyzed
      -  452   -
            * @return true if there was evidence within the pom that we could use; otherwise false
      -  453   -
            */
      -  454   -
           public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) {
      -  455  1
               boolean foundSomething = false;
      -  456  1
               boolean addAsIdentifier = true;
      -  457  1
               if (pom == null) {
      -  458  0
                   return foundSomething;
      -  459   -
               }
      -  460  1
               String groupid = pom.getGroupId();
      -  461  1
               String parentGroupId = pom.getParentGroupId();
      -  462  1
               String artifactid = pom.getArtifactId();
      -  463  1
               String parentArtifactId = pom.getParentArtifactId();
      -  464  1
               String version = pom.getVersion();
      -  465  1
               String parentVersion = pom.getParentVersion();
      -  466   -
       
      -  467  1
               if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) {
      -  468  0
                   parentGroupId = null;
      -  469  0
                   parentArtifactId = null;
      -  470  0
                   parentVersion = null;
      -  471   -
               }
      -  472   -
       
      -  473  1
               if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) {
      -  474  0
                   groupid = parentGroupId;
      -  475   -
               }
      -  476   -
       
      -  477  1
               final String originalGroupID = groupid;
      -  478  1
               if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
      -  479  1
                   groupid = groupid.substring(4);
      -  480   -
               }
      -  481   -
       
      -  482  1
               if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) {
      -  483  0
                   artifactid = parentArtifactId;
      -  484   -
               }
      -  485   -
       
      -  486  1
               final String originalArtifactID = artifactid;
      -  487  1
               if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
      -  488  0
                   artifactid = artifactid.substring(4);
      -  489   -
               }
      -  490   -
       
      -  491  1
               if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) {
      -  492  1
                   version = parentVersion;
      -  493   -
               }
      -  494   -
       
      -  495  1
               if (groupid != null && !groupid.isEmpty()) {
      -  496  1
                   foundSomething = true;
      -  497  1
                   dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
      -  498  1
                   dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
      -  499  1
                   addMatchingValues(classes, groupid, dependency.getVendorEvidence());
      -  500  1
                   addMatchingValues(classes, groupid, dependency.getProductEvidence());
      -  501  1
                   if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) {
      -  502  1
                       dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM);
      -  503  1
                       dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW);
      -  504  1
                       addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence());
      -  505  1
                       addMatchingValues(classes, parentGroupId, dependency.getProductEvidence());
      -  506   -
                   }
      -  507   -
               } else {
      -  508  0
                   addAsIdentifier = false;
      -  509   -
               }
      -  510   -
       
      -  511  1
               if (artifactid != null && !artifactid.isEmpty()) {
      -  512  1
                   foundSomething = true;
      -  513  1
                   dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST);
      -  514  1
                   dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
      -  515  1
                   addMatchingValues(classes, artifactid, dependency.getVendorEvidence());
      -  516  1
                   addMatchingValues(classes, artifactid, dependency.getProductEvidence());
      -  517  1
                   if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) {
      -  518  1
                       dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM);
      -  519  1
                       dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW);
      -  520  1
                       addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence());
      -  521  1
                       addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence());
      -  522   -
                   }
      -  523   -
               } else {
      -  524  0
                   addAsIdentifier = false;
      -  525   -
               }
      -  526   -
       
      -  527  1
               if (version != null && !version.isEmpty()) {
      -  528  1
                   foundSomething = true;
      -  529  1
                   dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
      -  530  1
                   if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) {
      -  531  0
                       dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW);
      -  532   -
                   }
      -  533   -
               } else {
      -  534  0
                   addAsIdentifier = false;
      -  535   -
               }
      -  536   -
       
      -  537  1
               if (addAsIdentifier) {
      -  538  1
                   dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH);
      -  539   -
               }
      -  540   -
       
      -  541   -
               // org name
      -  542  1
               final String org = pom.getOrganization();
      -  543  1
               if (org != null && !org.isEmpty()) {
      -  544  0
                   dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH);
      -  545  0
                   dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW);
      -  546  0
                   addMatchingValues(classes, org, dependency.getVendorEvidence());
      -  547  0
                   addMatchingValues(classes, org, dependency.getProductEvidence());
      -  548   -
               }
      -  549   -
               //pom name
      -  550  1
               final String pomName = pom.getName();
      -  551  1
               if (pomName
      -  552  1
                       != null && !pomName.isEmpty()) {
      -  553  1
                   foundSomething = true;
      -  554  1
                   dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
      -  555  1
                   dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
      -  556  1
                   addMatchingValues(classes, pomName, dependency.getVendorEvidence());
      -  557  1
                   addMatchingValues(classes, pomName, dependency.getProductEvidence());
      -  558   -
               }
      -  559   -
       
      -  560   -
               //Description
      -  561  1
               final String description = pom.getDescription();
      -  562  1
               if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) {
      -  563  0
                   foundSomething = true;
      -  564  0
                   final String trimmedDescription = addDescription(dependency, description, "pom", "description");
      -  565  0
                   addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence());
      -  566  0
                   addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
      -  567   -
               }
      -  568   -
       
      -  569  1
               extractLicense(pom, dependency);
      -  570  1
               return foundSomething;
      -  571   +
               } finally {
      +  419  0
                   closeStream(fos);
      +  420  0
                   closeStream(input);
      +  421  0
               }
      +  422  0
               return PomUtils.readPom(file);
      +  423  
           }
      -  572   +  424  
       
      -  573   +  425  
           /**
      -  574   -
            * Analyzes the path information of the classes contained within the JarAnalyzer to try and determine possible vendor or
      -  575   -
            * product names. If any are found they are stored in the packageVendor and packageProduct hashSets.
      -  576   +  426   +
            * Silently closes an input stream ignoring errors.
      +  427  
            *
      -  577   -
            * @param classNames a list of class names
      +  428   +
            * @param stream an input stream to close
      +  429   +
            */
      +  430   +
           private void closeStream(InputStream stream) {
      +  431  0
               if (stream != null) {
      +  432   +
                   try {
      +  433  0
                       stream.close();
      +  434  0
                   } catch (IOException ex) {
      +  435  0
                       LOGGER.trace("", ex);
      +  436  0
                   }
      +  437   +
               }
      +  438  0
           }
      +  439   +
       
      +  440   +
           /**
      +  441   +
            * Silently closes an output stream ignoring errors.
      +  442   +
            *
      +  443   +
            * @param stream an output stream to close
      +  444   +
            */
      +  445   +
           private void closeStream(OutputStream stream) {
      +  446  0
               if (stream != null) {
      +  447   +
                   try {
      +  448  0
                       stream.close();
      +  449  0
                   } catch (IOException ex) {
      +  450  0
                       LOGGER.trace("", ex);
      +  451  0
                   }
      +  452   +
               }
      +  453  0
           }
      +  454   +
       
      +  455   +
           /**
      +  456   +
            * Sets evidence from the pom on the supplied dependency.
      +  457   +
            *
      +  458   +
            * @param dependency the dependency to set data on
      +  459   +
            * @param pom the information from the pom
      +  460   +
            * @param classes a collection of ClassNameInformation - containing data
      +  461   +
            * about the fully qualified class names within the JAR file being analyzed
      +  462   +
            * @return true if there was evidence within the pom that we could use;
      +  463   +
            * otherwise false
      +  464   +
            */
      +  465   +
           public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) {
      +  466  4
               boolean foundSomething = false;
      +  467  4
               boolean addAsIdentifier = true;
      +  468  4
               if (pom == null) {
      +  469  0
                   return foundSomething;
      +  470   +
               }
      +  471  4
               String groupid = pom.getGroupId();
      +  472  4
               String parentGroupId = pom.getParentGroupId();
      +  473  4
               String artifactid = pom.getArtifactId();
      +  474  4
               String parentArtifactId = pom.getParentArtifactId();
      +  475  4
               String version = pom.getVersion();
      +  476  4
               String parentVersion = pom.getParentVersion();
      +  477   +
       
      +  478  4
               if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) {
      +  479  0
                   parentGroupId = null;
      +  480  0
                   parentArtifactId = null;
      +  481  0
                   parentVersion = null;
      +  482   +
               }
      +  483   +
       
      +  484  4
               if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) {
      +  485  0
                   groupid = parentGroupId;
      +  486   +
               }
      +  487   +
       
      +  488  4
               final String originalGroupID = groupid;
      +  489  4
               if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
      +  490  2
                   groupid = groupid.substring(4);
      +  491   +
               }
      +  492   +
       
      +  493  4
               if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) {
      +  494  0
                   artifactid = parentArtifactId;
      +  495   +
               }
      +  496   +
       
      +  497  4
               final String originalArtifactID = artifactid;
      +  498  4
               if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
      +  499  0
                   artifactid = artifactid.substring(4);
      +  500   +
               }
      +  501   +
       
      +  502  4
               if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) {
      +  503  2
                   version = parentVersion;
      +  504   +
               }
      +  505   +
       
      +  506  4
               if (groupid != null && !groupid.isEmpty()) {
      +  507  4
                   foundSomething = true;
      +  508  4
                   dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
      +  509  4
                   dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
      +  510  4
                   addMatchingValues(classes, groupid, dependency.getVendorEvidence());
      +  511  4
                   addMatchingValues(classes, groupid, dependency.getProductEvidence());
      +  512  4
                   if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) {
      +  513  2
                       dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM);
      +  514  2
                       dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW);
      +  515  2
                       addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence());
      +  516  2
                       addMatchingValues(classes, parentGroupId, dependency.getProductEvidence());
      +  517   +
                   }
      +  518   +
               } else {
      +  519  0
                   addAsIdentifier = false;
      +  520   +
               }
      +  521   +
       
      +  522  4
               if (artifactid != null && !artifactid.isEmpty()) {
      +  523  4
                   foundSomething = true;
      +  524  4
                   dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST);
      +  525  4
                   dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
      +  526  4
                   addMatchingValues(classes, artifactid, dependency.getVendorEvidence());
      +  527  4
                   addMatchingValues(classes, artifactid, dependency.getProductEvidence());
      +  528  4
                   if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) {
      +  529  2
                       dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM);
      +  530  2
                       dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW);
      +  531  2
                       addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence());
      +  532  2
                       addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence());
      +  533   +
                   }
      +  534   +
               } else {
      +  535  0
                   addAsIdentifier = false;
      +  536   +
               }
      +  537   +
       
      +  538  4
               if (version != null && !version.isEmpty()) {
      +  539  4
                   foundSomething = true;
      +  540  4
                   dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
      +  541  4
                   if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) {
      +  542  0
                       dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW);
      +  543   +
                   }
      +  544   +
               } else {
      +  545  0
                   addAsIdentifier = false;
      +  546   +
               }
      +  547   +
       
      +  548  4
               if (addAsIdentifier) {
      +  549  4
                   dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH);
      +  550   +
               }
      +  551   +
       
      +  552   +
               // org name
      +  553  4
               final String org = pom.getOrganization();
      +  554  4
               if (org != null && !org.isEmpty()) {
      +  555  0
                   dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH);
      +  556  0
                   dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW);
      +  557  0
                   addMatchingValues(classes, org, dependency.getVendorEvidence());
      +  558  0
                   addMatchingValues(classes, org, dependency.getProductEvidence());
      +  559   +
               }
      +  560   +
               //pom name
      +  561  4
               final String pomName = pom.getName();
      +  562  4
               if (pomName
      +  563  4
                       != null && !pomName.isEmpty()) {
      +  564  4
                   foundSomething = true;
      +  565  4
                   dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
      +  566  4
                   dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
      +  567  4
                   addMatchingValues(classes, pomName, dependency.getVendorEvidence());
      +  568  4
                   addMatchingValues(classes, pomName, dependency.getProductEvidence());
      +  569   +
               }
      +  570   +
       
      +  571   +
               //Description
      +  572  4
               final String description = pom.getDescription();
      +  573  4
               if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) {
      +  574  2
                   foundSomething = true;
      +  575  2
                   final String trimmedDescription = addDescription(dependency, description, "pom", "description");
      +  576  2
                   addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence());
      +  577  2
                   addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
       578   -
            * @param dependency a dependency to analyze
      +
               }
       579   -
            * @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence.
      -  580   -
            */
      -  581   -
           protected void analyzePackageNames(List<ClassNameInformation> classNames,
      -  582   -
                   Dependency dependency, boolean addPackagesAsEvidence) {
      -  583  5
               final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>();
      -  584  5
               final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>();
      -  585  5
               analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers);
      -  586  
       
      -  587  5
               final int classCount = classNames.size();
      -  588  5
               final EvidenceCollection vendor = dependency.getVendorEvidence();
      -  589  5
               final EvidenceCollection product = dependency.getProductEvidence();
      -  590   +  580  4
               final String projectURL = pom.getProjectURL();
      +  581  4
               if (projectURL != null && !projectURL.trim().isEmpty()) {
      +  582  2
                   dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST);
      +  583   +
               }
      +  584  
       
      -  591  5
               for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) {
      -  592  48
                   final float ratio = entry.getValue() / (float) classCount;
      -  593  48
                   if (ratio > 0.5) {
      -  594   -
                       //TODO remove weighting
      -  595  10
                       vendor.addWeighting(entry.getKey());
      -  596  10
                       if (addPackagesAsEvidence && entry.getKey().length() > 1) {
      -  597  8
                           vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
      -  598   -
                       }
      -  599   -
                   }
      -  600  48
               }
      -  601  5
               for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) {
      -  602  985
                   final float ratio = entry.getValue() / (float) classCount;
      -  603  985
                   if (ratio > 0.5) {
      -  604  5
                       product.addWeighting(entry.getKey());
      -  605  5
                       if (addPackagesAsEvidence && entry.getKey().length() > 1) {
      -  606  4
                           product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
      -  607   -
                       }
      -  608   -
                   }
      -  609  985
               }
      -  610  5
           }
      -  611   +  585  4
               extractLicense(pom, dependency);
      +  586  4
               return foundSomething;
      +  587   +
           }
      +  588  
       
      -  612   +  589  
           /**
      -  613   -
            * <p>
      -  614   -
            * Reads the manifest from the JAR file and collects the entries. Some vendorKey entries are:</p>
      -  615   -
            * <ul><li>Implementation Title</li>
      -  616   -
            * <li>Implementation Version</li> <li>Implementation Vendor</li>
      -  617   -
            * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle Version</li> <li>Bundle Vendor</li> <li>Bundle
      -  618   -
            * Description</li> <li>Main Class</li> </ul>
      -  619   -
            * However, all but a handful of specific entries are read in.
      -  620   +  590   +
            * Analyzes the path information of the classes contained within the
      +  591   +
            * JarAnalyzer to try and determine possible vendor or product names. If any
      +  592   +
            * are found they are stored in the packageVendor and packageProduct
      +  593   +
            * hashSets.
      +  594  
            *
      -  621   -
            * @param dependency A reference to the dependency
      -  622   -
            * @param classInformation a collection of class information
      -  623   -
            * @return whether evidence was identified parsing the manifest
      -  624   -
            * @throws IOException if there is an issue reading the JAR file
      -  625   +  595   +
            * @param classNames a list of class names
      +  596   +
            * @param dependency a dependency to analyze
      +  597   +
            * @param addPackagesAsEvidence a flag indicating whether or not package
      +  598   +
            * names should be added as evidence.
      +  599  
            */
      -  626   -
           protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException {
      -  627  6
               boolean foundSomething = false;
      -  628  6
               JarFile jar = null;
      -  629   -
               try {
      -  630  6
                   jar = new JarFile(dependency.getActualFilePath());
      -  631  6
                   final Manifest manifest = jar.getManifest();
      -  632  6
                   if (manifest == null) {
      -  633   -
                       //don't log this for javadoc or sources jar files
      -  634  0
                       if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar")
      -  635  0
                               && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar")
      -  636  0
                               && !dependency.getFileName().toLowerCase().endsWith("-src.jar")
      -  637  0
                               && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) {
      -  638  0
                           LOGGER.debug("Jar file '{}' does not contain a manifest.",
      -  639  0
                                   dependency.getFileName());
      -  640   +  600   +
           protected void analyzePackageNames(List<ClassNameInformation> classNames,
      +  601   +
                   Dependency dependency, boolean addPackagesAsEvidence) {
      +  602  12
               final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>();
      +  603  12
               final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>();
      +  604  12
               analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers);
      +  605   +
       
      +  606  12
               final int classCount = classNames.size();
      +  607  12
               final EvidenceCollection vendor = dependency.getVendorEvidence();
      +  608  12
               final EvidenceCollection product = dependency.getProductEvidence();
      +  609   +
       
      +  610  12
               for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) {
      +  611  96
                   final float ratio = entry.getValue() / (float) classCount;
      +  612  96
                   if (ratio > 0.5) {
      +  613   +
                       //TODO remove weighting
      +  614  20
                       vendor.addWeighting(entry.getKey());
      +  615  20
                       if (addPackagesAsEvidence && entry.getKey().length() > 1) {
      +  616  16
                           vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
      +  617  
                       }
      -  641  0
                       return false;
      -  642   +  618  
                   }
      -  643  6
                   final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
      -  644  6
                   final EvidenceCollection productEvidence = dependency.getProductEvidence();
      -  645  6
                   final EvidenceCollection versionEvidence = dependency.getVersionEvidence();
      -  646   -
       
      -  647  6
                   String source = "Manifest";
      -  648  6
                   String specificationVersion = null;
      -  649  6
                   boolean hasImplementationVersion = false;
      -  650   -
       
      -  651  6
                   Attributes atts = manifest.getMainAttributes();
      -  652  6
                   for (Entry<Object, Object> entry : atts.entrySet()) {
      -  653  70
                       String key = entry.getKey().toString();
      -  654  70
                       String value = atts.getValue(key);
      -  655  70
                       if (HTML_DETECTION_PATTERN.matcher(value).find()) {
      -  656  0
                           value = Jsoup.parse(value).text();
      -  657   +  619  96
               }
      +  620  12
               for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) {
      +  621  1970
                   final float ratio = entry.getValue() / (float) classCount;
      +  622  1970
                   if (ratio > 0.5) {
      +  623  10
                       product.addWeighting(entry.getKey());
      +  624  10
                       if (addPackagesAsEvidence && entry.getKey().length() > 1) {
      +  625  8
                           product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
      +  626  
                       }
      -  658  70
                       if (IGNORE_VALUES.contains(value)) {
      -  659  0
                           continue;
      -  660  70
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
      -  661  1
                           foundSomething = true;
      -  662  1
                           productEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  663  1
                           addMatchingValues(classInformation, value, productEvidence);
      -  664  69
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
      -  665  2
                           hasImplementationVersion = true;
      -  666  2
                           foundSomething = true;
      -  667  2
                           versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  668  67
                       } else if ("specification-version".equalsIgnoreCase(key)) {
      -  669  1
                           specificationVersion = key;
      -  670  66
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
      -  671  1
                           foundSomething = true;
      -  672  1
                           vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  673  1
                           addMatchingValues(classInformation, value, vendorEvidence);
      -  674  65
                       } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) {
      -  675  0
                           foundSomething = true;
      -  676  0
                           vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  677  0
                           addMatchingValues(classInformation, value, vendorEvidence);
      -  678  65
                       } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) {
      -  679  2
                           foundSomething = true;
      -  680  2
                           addDescription(dependency, value, "manifest", key);
      -  681   -
                           //productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  682  2
                           addMatchingValues(classInformation, value, productEvidence);
      -  683  63
                       } else if (key.equalsIgnoreCase(BUNDLE_NAME)) {
      -  684  3
                           foundSomething = true;
      -  685  3
                           productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  686  3
                           addMatchingValues(classInformation, value, productEvidence);
      -  687   -
       //                //the following caused false positives.
      -  688   -
       //                } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) {
      -  689   -
       //                    foundSomething = true;
      -  690   -
       //                    vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  691   -
       //                    addMatchingValues(classInformation, value, vendorEvidence);
      -  692  60
                       } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) {
      -  693  3
                           foundSomething = true;
      -  694  3
                           versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  695  57
                       } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) {
      -  696  3
                           continue;
      -  697   -
                           //skipping main class as if this has important information to add
      -  698   -
                           // it will be added during class name analysis...  if other fields
      -  699   -
                           // have the information from the class name then they will get added...
      -  700   -
       //                    foundSomething = true;
      -  701   -
       //                    productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  702   -
       //                    vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  703   -
       //                    addMatchingValues(classInformation, value, vendorEvidence);
      -  704   -
       //                    addMatchingValues(classInformation, value, productEvidence);
      -  705   -
                       } else {
      -  706  54
                           key = key.toLowerCase();
      -  707  54
                           if (!IGNORE_KEYS.contains(key)
      -  708  15
                                   && !key.endsWith("jdk")
      -  709  15
                                   && !key.contains("lastmodified")
      -  710  14
                                   && !key.endsWith("package")
      -  711  14
                                   && !key.endsWith("classpath")
      -  712  14
                                   && !key.endsWith("class-path")
      -  713  14
                                   && !key.endsWith("-scm") //todo change this to a regex?
      -  714  14
                                   && !key.startsWith("scm-")
      -  715  14
                                   && !value.trim().startsWith("scm:")
      -  716  14
                                   && !isImportPackage(key, value)
      -  717  14
                                   && !isPackage(key, value)) {
      -  718   +  627   +
                   }
      +  628  1970
               }
      +  629  12
           }
      +  630  
       
      -  719  13
                               foundSomething = true;
      -  720  13
                               if (key.contains("version")) {
      -  721  0
                                   if (!key.contains("specification")) {
      -  722  0
                                       versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  723   +  631   +
           /**
      +  632   +
            * <p>
      +  633   +
            * Reads the manifest from the JAR file and collects the entries. Some
      +  634   +
            * vendorKey entries are:</p>
      +  635   +
            * <ul><li>Implementation Title</li>
      +  636   +
            * <li>Implementation Version</li> <li>Implementation Vendor</li>
      +  637   +
            * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle
      +  638   +
            * Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main
      +  639   +
            * Class</li> </ul>
      +  640   +
            * However, all but a handful of specific entries are read in.
      +  641   +
            *
      +  642   +
            * @param dependency A reference to the dependency
      +  643   +
            * @param classInformation a collection of class information
      +  644   +
            * @return whether evidence was identified parsing the manifest
      +  645   +
            * @throws IOException if there is an issue reading the JAR file
      +  646   +
            */
      +  647   +
           protected boolean parseManifest(Dependency dependency,
      +  648   +
                   List<ClassNameInformation> classInformation)
      +  649   +
                   throws IOException {
      +  650  14
               boolean foundSomething = false;
      +  651  14
               JarFile jar = null;
      +  652   +
               try {
      +  653  14
                   jar = new JarFile(dependency.getActualFilePath());
      +  654  14
                   final Manifest manifest = jar.getManifest();
      +  655  14
                   if (manifest == null) {
      +  656  0
                       if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar")
      +  657  0
                               && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar")
      +  658  0
                               && !dependency.getFileName().toLowerCase().endsWith("-src.jar")
      +  659  0
                               && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) {
      +  660  0
                           LOGGER.debug("Jar file '{}' does not contain a manifest.",
      +  661  0
                                   dependency.getFileName());
      +  662   +
                       }
      +  663  0
                       return false;
      +  664   +
                   }
      +  665  14
                   final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
      +  666  14
                   final EvidenceCollection productEvidence = dependency.getProductEvidence();
      +  667  14
                   final EvidenceCollection versionEvidence = dependency.getVersionEvidence();
      +  668   +
       
      +  669  14
                   String source = "Manifest";
      +  670  14
                   String specificationVersion = null;
      +  671  14
                   boolean hasImplementationVersion = false;
      +  672  14
                   Attributes atts = manifest.getMainAttributes();
      +  673  14
                   for (Entry<Object, Object> entry : atts.entrySet()) {
      +  674  144
                       String key = entry.getKey().toString();
      +  675  144
                       String value = atts.getValue(key);
      +  676  144
                       if (HTML_DETECTION_PATTERN.matcher(value).find()) {
      +  677  0
                           value = Jsoup.parse(value).text();
      +  678   +
                       }
      +  679  144
                       if (IGNORE_VALUES.contains(value)) {
      +  680  0
                           continue;
      +  681  144
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
      +  682  2
                           foundSomething = true;
      +  683  2
                           productEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  684  2
                           addMatchingValues(classInformation, value, productEvidence);
      +  685  142
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
      +  686  4
                           hasImplementationVersion = true;
      +  687  4
                           foundSomething = true;
      +  688  4
                           versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  689  138
                       } else if ("specification-version".equalsIgnoreCase(key)) {
      +  690  2
                           specificationVersion = key;
      +  691  136
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
      +  692  2
                           foundSomething = true;
      +  693  2
                           vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  694  2
                           addMatchingValues(classInformation, value, vendorEvidence);
      +  695  134
                       } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) {
      +  696  0
                           foundSomething = true;
      +  697  0
                           vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  698  0
                           addMatchingValues(classInformation, value, vendorEvidence);
      +  699  134
                       } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) {
      +  700  4
                           foundSomething = true;
      +  701  4
                           addDescription(dependency, value, "manifest", key);
      +  702  4
                           addMatchingValues(classInformation, value, productEvidence);
      +  703  130
                       } else if (key.equalsIgnoreCase(BUNDLE_NAME)) {
      +  704  6
                           foundSomething = true;
      +  705  6
                           productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  706  6
                           addMatchingValues(classInformation, value, productEvidence);
      +  707   +
       //                //the following caused false positives.
      +  708   +
       //                } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) {
      +  709   +
       //                    foundSomething = true;
      +  710   +
       //                    vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  711   +
       //                    addMatchingValues(classInformation, value, vendorEvidence);
      +  712  124
                       } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) {
      +  713  6
                           foundSomething = true;
      +  714  6
                           versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  715  118
                       } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) {
      +  716  6
                           continue;
      +  717   +
                           //skipping main class as if this has important information to add
      +  718   +
                           // it will be added during class name analysis...  if other fields
      +  719   +
                           // have the information from the class name then they will get added...
      +  720   +
                       } else {
      +  721  112
                           key = key.toLowerCase();
      +  722  112
                           if (!IGNORE_KEYS.contains(key)
      +  723  30
                                   && !key.endsWith("jdk")
      +  724  30
                                   && !key.contains("lastmodified")
      +  725  28
                                   && !key.endsWith("package")
      +  726  28
                                   && !key.endsWith("classpath")
      +  727  28
                                   && !key.endsWith("class-path")
      +  728  28
                                   && !key.endsWith("-scm") //todo change this to a regex?
      +  729  28
                                   && !key.startsWith("scm-")
      +  730  28
                                   && !value.trim().startsWith("scm:")
      +  731  28
                                   && !isImportPackage(key, value)
      +  732  28
                                   && !isPackage(key, value)) {
      +  733  26
                               foundSomething = true;
      +  734  26
                               if (key.contains("version")) {
      +  735  0
                                   if (!key.contains("specification")) {
      +  736  0
                                       versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  737  
                                   }
      -  724  13
                               } else if ("build-id".equals(key)) {
      -  725  0
                                   int pos = value.indexOf('(');
      -  726  0
                                   if (pos >= 0) {
      -  727  0
                                       value = value.substring(0, pos - 1);
      -  728   +  738  26
                               } else if ("build-id".equals(key)) {
      +  739  0
                                   int pos = value.indexOf('(');
      +  740  0
                                   if (pos >= 0) {
      +  741  0
                                       value = value.substring(0, pos - 1);
      +  742  
                                   }
      -  729  0
                                   pos = value.indexOf('[');
      -  730  0
                                   if (pos >= 0) {
      -  731  0
                                       value = value.substring(0, pos - 1);
      -  732   +  743  0
                                   pos = value.indexOf('[');
      +  744  0
                                   if (pos >= 0) {
      +  745  0
                                       value = value.substring(0, pos - 1);
      +  746  
                                   }
      -  733  0
                                   versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  734  0
                               } else if (key.contains("title")) {
      -  735  1
                                   productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  736  1
                                   addMatchingValues(classInformation, value, productEvidence);
      -  737  12
                               } else if (key.contains("vendor")) {
      -  738  0
                                   if (key.contains("specification")) {
      -  739  0
                                       vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
      -  740   -
                                   } else {
      -  741  0
                                       vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  742  0
                                       addMatchingValues(classInformation, value, vendorEvidence);
      -  743   -
                                   }
      -  744  12
                               } else if (key.contains("name")) {
      -  745  3
                                   productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  746  3
                                   vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  747  3
                                   addMatchingValues(classInformation, value, vendorEvidence);
      -  748  3
                                   addMatchingValues(classInformation, value, productEvidence);
      -  749  9
                               } else if (key.contains("license")) {
      -  750  2
                                   addLicense(dependency, value);
      -  751   -
                               } else {
      -  752  7
                                   if (key.contains("description")) {
      -  753  0
                                       addDescription(dependency, value, "manifest", key);
      +  747  0
                                   versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  748  0
                               } else if (key.contains("title")) {
      +  749  2
                                   productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  750  2
                                   addMatchingValues(classInformation, value, productEvidence);
      +  751  24
                               } else if (key.contains("vendor")) {
      +  752  0
                                   if (key.contains("specification")) {
      +  753  0
                                       vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
       754  
                                   } else {
      -  755  7
                                       productEvidence.addEvidence(source, key, value, Confidence.LOW);
      -  756  7
                                       vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
      -  757  7
                                       addMatchingValues(classInformation, value, vendorEvidence);
      -  758  7
                                       addMatchingValues(classInformation, value, productEvidence);
      -  759  7
                                       if (value.matches(".*\\d.*")) {
      -  760  3
                                           final StringTokenizer tokenizer = new StringTokenizer(value, " ");
      -  761  15
                                           while (tokenizer.hasMoreElements()) {
      -  762  12
                                               final String s = tokenizer.nextToken();
      -  763  12
                                               if (s.matches("^[0-9.]+$")) {
      -  764  1
                                                   versionEvidence.addEvidence(source, key, s, Confidence.LOW);
      -  765   -
                                               }
      -  766  12
                                           }
      -  767   -
                                       }
      -  768   +  755  0
                                       vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  756  0
                                       addMatchingValues(classInformation, value, vendorEvidence);
      +  757  
                                   }
      -  769   +  758  24
                               } else if (key.contains("name")) {
      +  759  6
                                   productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  760  6
                                   vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  761  6
                                   addMatchingValues(classInformation, value, vendorEvidence);
      +  762  6
                                   addMatchingValues(classInformation, value, productEvidence);
      +  763  18
                               } else if (key.contains("license")) {
      +  764  4
                                   addLicense(dependency, value);
      +  765  14
                               } else if (key.contains("description")) {
      +  766  0
                                   addDescription(dependency, value, "manifest", key);
      +  767   +
                               } else {
      +  768  14
                                   productEvidence.addEvidence(source, key, value, Confidence.LOW);
      +  769  14
                                   vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
      +  770  14
                                   addMatchingValues(classInformation, value, vendorEvidence);
      +  771  14
                                   addMatchingValues(classInformation, value, productEvidence);
      +  772  14
                                   if (value.matches(".*\\d.*")) {
      +  773  6
                                       final StringTokenizer tokenizer = new StringTokenizer(value, " ");
      +  774  30
                                       while (tokenizer.hasMoreElements()) {
      +  775  24
                                           final String s = tokenizer.nextToken();
      +  776  24
                                           if (s.matches("^[0-9.]+$")) {
      +  777  2
                                               versionEvidence.addEvidence(source, key, s, Confidence.LOW);
      +  778   +
                                           }
      +  779  24
                                       }
      +  780   +
                                   }
      +  781  
                               }
      -  770   +  782  
                           }
      -  771   +  783  
                       }
      -  772  67
                   }
      -  773   +  784  138
                   }
      +  785  
       
      -  774  6
                   final Map<String, Attributes> entries = manifest.getEntries();
      -  775  6
                   for (Iterator<String> it = entries.keySet().iterator(); it.hasNext();) {
      -  776  8
                       final String name = it.next();
      -  777  8
                       source = "manifest: " + name;
      -  778  8
                       atts = entries.get(name);
      -  779  8
                       for (Entry<Object, Object> entry : atts.entrySet()) {
      -  780  38
                           final String key = entry.getKey().toString();
      -  781  38
                           final String value = atts.getValue(key);
      -  782  38
                           if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
      -  783  8
                               foundSomething = true;
      -  784  8
                               productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  785  8
                               addMatchingValues(classInformation, value, productEvidence);
      -  786  30
                           } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
      -  787  5
                               foundSomething = true;
      -  788  5
                               versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  789  25
                           } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
      -  790  5
                               foundSomething = true;
      -  791  5
                               vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  792  5
                               addMatchingValues(classInformation, value, vendorEvidence);
      -  793  20
                           } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) {
      -  794  4
                               foundSomething = true;
      -  795  4
                               productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  796  4
                               addMatchingValues(classInformation, value, productEvidence);
      -  797   -
                           }
      -  798  38
                       }
      -  799  8
                   }
      -  800  6
                   if (specificationVersion != null && !hasImplementationVersion) {
      -  801  0
                       foundSomething = true;
      -  802  0
                       versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH);
      -  803   -
                   }
      -  804   -
               } finally {
      -  805  6
                   if (jar != null) {
      -  806  6
                       jar.close();
      -  807   -
                   }
      +  786  14
                   for (Map.Entry<String, Attributes> item : manifest.getEntries().entrySet()) {
      +  787  16
                       final String name = item.getKey();
      +  788  16
                       source = "manifest: " + name;
      +  789  16
                       atts = item.getValue();
      +  790  16
                       for (Entry<Object, Object> entry : atts.entrySet()) {
      +  791  76
                           final String key = entry.getKey().toString();
      +  792  76
                           final String value = atts.getValue(key);
      +  793  76
                           if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
      +  794  16
                               foundSomething = true;
      +  795  16
                               productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  796  16
                               addMatchingValues(classInformation, value, productEvidence);
      +  797  60
                           } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
      +  798  10
                               foundSomething = true;
      +  799  10
                               versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  800  50
                           } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
      +  801  10
                               foundSomething = true;
      +  802  10
                               vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  803  10
                               addMatchingValues(classInformation, value, vendorEvidence);
      +  804  40
                           } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) {
      +  805  8
                               foundSomething = true;
      +  806  8
                               productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  807  8
                               addMatchingValues(classInformation, value, productEvidence);
       808   -
               }
      -  809  6
               return foundSomething;
      -  810   -
           }
      -  811   -
       
      -  812   -
           /**
      -  813   -
            * Adds a description to the given dependency. If the description contains one of the following strings beyond 100 characters,
      +
                           }
      +  809  76
                       }
      +  810  16
                   }
      +  811  14
                   if (specificationVersion != null && !hasImplementationVersion) {
      +  812  0
                       foundSomething = true;
      +  813  0
                       versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH);
       814   -
            * then the description used will be trimmed to that position:
      +
                   }
       815   -
            * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses "</li></ul>
      -  816   -
            *
      -  817   -
            * @param dependency a dependency
      +
               } finally {
      +  816  14
                   if (jar != null) {
      +  817  14
                       jar.close();
       818   -
            * @param description the description
      +
                   }
       819   -
            * @param source the source of the evidence
      -  820   -
            * @param key the "name" of the evidence
      +
               }
      +  820  14
               return foundSomething;
       821   -
            * @return if the description is trimmed, the trimmed version is returned; otherwise the original description is returned
      +
           }
       822   -
            */
      -  823   -
           public static String addDescription(Dependency dependency, String description, String source, String key) {
      -  824  9
               if (dependency.getDescription() == null) {
      -  825  9
                   dependency.setDescription(description);
      -  826   -
               }
      -  827   -
               String desc;
      -  828  9
               if (HTML_DETECTION_PATTERN.matcher(description).find()) {
      -  829  0
                   desc = Jsoup.parse(description).text();
      -  830   -
               } else {
      -  831  9
                   desc = description;
      -  832   -
               }
      -  833  9
               dependency.setDescription(desc);
      -  834  9
               if (desc.length() > 100) {
      -  835  0
                   desc = desc.replaceAll("\\s\\s+", " ");
      -  836  0
                   final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100);
      -  837  0
                   final int posLike = desc.toLowerCase().indexOf("like ", 100);
      -  838  0
                   final int posWillUse = desc.toLowerCase().indexOf("will use ", 100);
      -  839  0
                   final int posUses = desc.toLowerCase().indexOf(" uses ", 100);
      -  840  0
                   int pos = -1;
      -  841  0
                   pos = Math.max(pos, posSuchAs);
      -  842  0
                   if (pos >= 0 && posLike >= 0) {
      -  843  0
                       pos = Math.min(pos, posLike);
      -  844   -
                   } else {
      -  845  0
                       pos = Math.max(pos, posLike);
      -  846   -
                   }
      -  847  0
                   if (pos >= 0 && posWillUse >= 0) {
      -  848  0
                       pos = Math.min(pos, posWillUse);
      -  849   -
                   } else {
      -  850  0
                       pos = Math.max(pos, posWillUse);
      -  851   -
                   }
      -  852  0
                   if (pos >= 0 && posUses >= 0) {
      -  853  0
                       pos = Math.min(pos, posUses);
      -  854   -
                   } else {
      -  855  0
                       pos = Math.max(pos, posUses);
      -  856   -
                   }
      -  857  
       
      -  858  0
                   if (pos > 0) {
      -  859  0
                       desc = desc.substring(0, pos) + "...";
      +  823   +
           /**
      +  824   +
            * Adds a description to the given dependency. If the description contains
      +  825   +
            * one of the following strings beyond 100 characters, then the description
      +  826   +
            * used will be trimmed to that position:
      +  827   +
            * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses
      +  828   +
            * "</li></ul>
      +  829   +
            *
      +  830   +
            * @param dependency a dependency
      +  831   +
            * @param description the description
      +  832   +
            * @param source the source of the evidence
      +  833   +
            * @param key the "name" of the evidence
      +  834   +
            * @return if the description is trimmed, the trimmed version is returned;
      +  835   +
            * otherwise the original description is returned
      +  836   +
            */
      +  837   +
           public static String addDescription(Dependency dependency, String description, String source, String key) {
      +  838  20
               if (dependency.getDescription() == null) {
      +  839  20
                   dependency.setDescription(description);
      +  840   +
               }
      +  841   +
               String desc;
      +  842  20
               if (HTML_DETECTION_PATTERN.matcher(description).find()) {
      +  843  0
                   desc = Jsoup.parse(description).text();
      +  844   +
               } else {
      +  845  20
                   desc = description;
      +  846   +
               }
      +  847  20
               dependency.setDescription(desc);
      +  848  20
               if (desc.length() > 100) {
      +  849  0
                   desc = desc.replaceAll("\\s\\s+", " ");
      +  850  0
                   final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100);
      +  851  0
                   final int posLike = desc.toLowerCase().indexOf("like ", 100);
      +  852  0
                   final int posWillUse = desc.toLowerCase().indexOf("will use ", 100);
      +  853  0
                   final int posUses = desc.toLowerCase().indexOf(" uses ", 100);
      +  854  0
                   int pos = -1;
      +  855  0
                   pos = Math.max(pos, posSuchAs);
      +  856  0
                   if (pos >= 0 && posLike >= 0) {
      +  857  0
                       pos = Math.min(pos, posLike);
      +  858   +
                   } else {
      +  859  0
                       pos = Math.max(pos, posLike);
       860  
                   }
      -  861  0
                   dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW);
      -  862  0
                   dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW);
      -  863  0
               } else {
      -  864  9
                   dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
      -  865  9
                   dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
      -  866   -
               }
      -  867  9
               return desc;
      +  861  0
                   if (pos >= 0 && posWillUse >= 0) {
      +  862  0
                       pos = Math.min(pos, posWillUse);
      +  863   +
                   } else {
      +  864  0
                       pos = Math.max(pos, posWillUse);
      +  865   +
                   }
      +  866  0
                   if (pos >= 0 && posUses >= 0) {
      +  867  0
                       pos = Math.min(pos, posUses);
       868   -
           }
      -  869   -
       
      +
                   } else {
      +  869  0
                       pos = Math.max(pos, posUses);
       870   -
           /**
      +
                   }
       871   -
            * Adds a license to the given dependency.
      -  872   -
            *
      -  873   -
            * @param d a dependency
      +
       
      +  872  0
                   if (pos > 0) {
      +  873  0
                       desc = desc.substring(0, pos) + "...";
       874   -
            * @param license the license
      -  875   -
            */
      -  876   -
           private void addLicense(Dependency d, String license) {
      -  877  2
               if (d.getLicense() == null) {
      -  878  2
                   d.setLicense(license);
      -  879  0
               } else if (!d.getLicense().contains(license)) {
      -  880  0
                   d.setLicense(d.getLicense() + NEWLINE + license);
      -  881   +
                   }
      +  875  0
                   dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW);
      +  876  0
                   dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW);
      +  877  0
               } else {
      +  878  20
                   dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
      +  879  20
                   dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
      +  880  
               }
      -  882  2
           }
      +  881  20
               return desc;
      +  882   +
           }
       883  
       
       884  
           /**
       885   -
            * The parent directory for the individual directories per archive.
      +
            * Adds a license to the given dependency.
       886   -
            */
      -  887  8
           private File tempFileLocation = null;
      +
            *
      +  887   +
            * @param d a dependency
       888   -
       
      +
            * @param license the license
       889   -
           /**
      +
            */
       890   -
            * Initializes the JarAnalyzer.
      -  891   -
            *
      -  892   -
            * @throws Exception is thrown if there is an exception creating a temporary directory
      -  893   -
            */
      -  894   -
           @Override
      +
           private void addLicense(Dependency d, String license) {
      +  891  4
               if (d.getLicense() == null) {
      +  892  4
                   d.setLicense(license);
      +  893  0
               } else if (!d.getLicense().contains(license)) {
      +  894  0
                   d.setLicense(d.getLicense() + NEWLINE + license);
       895   -
           public void initializeFileTypeAnalyzer() throws Exception {
      -  896  1
               final File baseDir = Settings.getTempDirectory();
      -  897  1
               tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      -  898  1
               if (!tempFileLocation.delete()) {
      -  899  0
                   final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      -  900  0
                   throw new AnalysisException(msg);
      -  901  
               }
      -  902  1
               if (!tempFileLocation.mkdirs()) {
      -  903  0
                   final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      -  904  0
                   throw new AnalysisException(msg);
      +  896  4
           }
      +  897   +
       
      +  898   +
           /**
      +  899   +
            * The parent directory for the individual directories per archive.
      +  900   +
            */
      +  901  20
           private File tempFileLocation = null;
      +  902   +
       
      +  903   +
           /**
      +  904   +
            * Initializes the JarAnalyzer.
       905   -
               }
      -  906  1
           }
      +
            *
      +  906   +
            * @throws Exception is thrown if there is an exception creating a temporary
       907   -
       
      +
            * directory
       908   -
           /**
      +
            */
       909   -
            * Deletes any files extracted from the JAR during analysis.
      -  910   -
            */
      -  911  
           @Override
      -  912   -
           public void close() {
      -  913  1
               if (tempFileLocation != null && tempFileLocation.exists()) {
      -  914  1
                   LOGGER.debug("Attempting to delete temporary files");
      -  915  1
                   final boolean success = FileUtils.delete(tempFileLocation);
      -  916  1
                   if (!success) {
      -  917  0
                       LOGGER.warn("Failed to delete some temporary files, see the log for more details");
      -  918   -
                   }
      -  919   +  910   +
           public void initializeFileTypeAnalyzer() throws Exception {
      +  911  2
               final File baseDir = Settings.getTempDirectory();
      +  912  2
               tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      +  913  2
               if (!tempFileLocation.delete()) {
      +  914  0
                   final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      +  915  0
                   throw new AnalysisException(msg);
      +  916  
               }
      -  920  1
           }
      -  921   -
       
      +  917  2
               if (!tempFileLocation.mkdirs()) {
      +  918  0
                   final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      +  919  0
                   throw new AnalysisException(msg);
      +  920   +
               }
      +  921  2
           }
       922   -
           /**
      +
       
       923   -
            * Determines if the key value pair from the manifest is for an "import" type entry for package names.
      +
           /**
       924   -
            *
      +
            * Deletes any files extracted from the JAR during analysis.
       925   -
            * @param key the key from the manifest
      +
            */
       926   -
            * @param value the value from the manifest
      +
           @Override
       927   -
            * @return true or false depending on if it is believed the entry is an "import" entry
      -  928   -
            */
      -  929   -
           private boolean isImportPackage(String key, String value) {
      -  930  14
               final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$");
      -  931  14
               final boolean matches = packageRx.matcher(value).matches();
      -  932  14
               return matches && (key.contains("import") || key.contains("include") || value.length() > 10);
      +
           public void close() {
      +  928  4
               if (tempFileLocation != null && tempFileLocation.exists()) {
      +  929  2
                   LOGGER.debug("Attempting to delete temporary files");
      +  930  2
                   final boolean success = FileUtils.delete(tempFileLocation);
      +  931  2
                   if (!success) {
      +  932  0
                       LOGGER.warn("Failed to delete some temporary files, see the log for more details");
       933   -
           }
      +
                   }
       934   -
       
      -  935   -
           /**
      +
               }
      +  935  4
           }
       936   -
            * Cycles through an enumeration of JarEntries, contained within the dependency, and returns a list of the class names. This
      +
       
       937   -
            * does not include core Java package names (i.e. java.* or javax.*).
      +
           /**
       938   -
            *
      +
            * Determines if the key value pair from the manifest is for an "import"
       939   -
            * @param dependency the dependency being analyzed
      +
            * type entry for package names.
       940   -
            * @return an list of fully qualified class names
      +
            *
       941   -
            */
      +
            * @param key the key from the manifest
       942   -
           private List<ClassNameInformation> collectClassNames(Dependency dependency) {
      -  943  5
               final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>();
      -  944  5
               JarFile jar = null;
      +
            * @param value the value from the manifest
      +  943   +
            * @return true or false depending on if it is believed the entry is an
      +  944   +
            * "import" entry
       945   -
               try {
      -  946  5
                   jar = new JarFile(dependency.getActualFilePath());
      -  947  5
                   final Enumeration<JarEntry> entries = jar.entries();
      -  948  1848
                   while (entries.hasMoreElements()) {
      -  949  1843
                       final JarEntry entry = entries.nextElement();
      -  950  1843
                       final String name = entry.getName().toLowerCase();
      +
            */
      +  946   +
           private boolean isImportPackage(String key, String value) {
      +  947  28
               final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$");
      +  948  28
               final boolean matches = packageRx.matcher(value).matches();
      +  949  28
               return matches && (key.contains("import") || key.contains("include") || value.length() > 10);
      +  950   +
           }
       951   -
                       //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs.
      -  952  1843
                       if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) {
      -  953  1535
                           final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6));
      -  954  1535
                           classNames.add(className);
      +
       
      +  952   +
           /**
      +  953   +
            * Cycles through an enumeration of JarEntries, contained within the
      +  954   +
            * dependency, and returns a list of the class names. This does not include
       955   -
                       }
      -  956  1843
                   }
      -  957  0
               } catch (IOException ex) {
      -  958  0
                   LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName());
      -  959  0
                   LOGGER.debug("", ex);
      +
            * core Java package names (i.e. java.* or javax.*).
      +  956   +
            *
      +  957   +
            * @param dependency the dependency being analyzed
      +  958   +
            * @return an list of fully qualified class names
      +  959   +
            */
       960   -
               } finally {
      -  961  5
                   if (jar != null) {
      -  962   -
                       try {
      -  963  5
                           jar.close();
      -  964  0
                       } catch (IOException ex) {
      -  965  0
                           LOGGER.trace("", ex);
      -  966  5
                       }
      -  967   -
                   }
      -  968   -
               }
      -  969  5
               return classNames;
      -  970   -
           }
      -  971   -
       
      -  972   -
           /**
      +
           private List<ClassNameInformation> collectClassNames(Dependency dependency) {
      +  961  12
               final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>();
      +  962  12
               JarFile jar = null;
      +  963   +
               try {
      +  964  12
                   jar = new JarFile(dependency.getActualFilePath());
      +  965  12
                   final Enumeration<JarEntry> entries = jar.entries();
      +  966  3704
                   while (entries.hasMoreElements()) {
      +  967  3692
                       final JarEntry entry = entries.nextElement();
      +  968  3692
                       final String name = entry.getName().toLowerCase();
      +  969   +
                       //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs.
      +  970  3692
                       if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) {
      +  971  3070
                           final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6));
      +  972  3070
                           classNames.add(className);
       973   -
            * Cycles through the list of class names and places the package levels 0-3 into the provided maps for vendor and product.
      -  974   -
            * This is helpful when analyzing vendor/product as many times this is included in the package name.
      -  975   -
            *
      -  976   -
            * @param classNames a list of class names
      -  977   -
            * @param vendor HashMap of possible vendor names from package names (e.g. owasp)
      +
                       }
      +  974  3692
                   }
      +  975  0
               } catch (IOException ex) {
      +  976  0
                   LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName());
      +  977  0
                   LOGGER.debug("", ex);
       978   -
            * @param product HashMap of possible product names from package names (e.g. dependencycheck)
      -  979   -
            */
      +
               } finally {
      +  979  12
                   if (jar != null) {
       980   -
           private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames,
      -  981   -
                   Map<String, Integer> vendor, Map<String, Integer> product) {
      -  982  5
               for (ClassNameInformation entry : classNames) {
      -  983  1535
                   final List<String> list = entry.getPackageStructure();
      -  984  1535
                   addEntry(vendor, list.get(0));
      +
                       try {
      +  981  12
                           jar.close();
      +  982  0
                       } catch (IOException ex) {
      +  983  0
                           LOGGER.trace("", ex);
      +  984  12
                       }
       985   -
       
      -  986  1535
                   if (list.size() == 2) {
      -  987  0
                       addEntry(product, list.get(1));
      +
                   }
      +  986   +
               }
      +  987  12
               return classNames;
       988   -
                   }
      -  989  1535
                   if (list.size() == 3) {
      -  990  345
                       addEntry(vendor, list.get(1));
      -  991  345
                       addEntry(product, list.get(1));
      -  992  345
                       addEntry(product, list.get(2));
      +
           }
      +  989   +
       
      +  990   +
           /**
      +  991   +
            * Cycles through the list of class names and places the package levels 0-3
      +  992   +
            * into the provided maps for vendor and product. This is helpful when
       993   -
                   }
      -  994  1535
                   if (list.size() >= 4) {
      -  995  1190
                       addEntry(vendor, list.get(1));
      -  996  1190
                       addEntry(vendor, list.get(2));
      -  997  1190
                       addEntry(product, list.get(1));
      -  998  1190
                       addEntry(product, list.get(2));
      -  999  1190
                       addEntry(product, list.get(3));
      +
            * analyzing vendor/product as many times this is included in the package
      +  994   +
            * name.
      +  995   +
            *
      +  996   +
            * @param classNames a list of class names
      +  997   +
            * @param vendor HashMap of possible vendor names from package names (e.g.
      +  998   +
            * owasp)
      +  999   +
            * @param product HashMap of possible product names from package names (e.g.
       1000   -
                   }
      -  1001  1535
               }
      -  1002  5
           }
      +
            * dependencycheck)
      +  1001   +
            */
      +  1002   +
           private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames,
       1003   -
       
      -  1004   -
           /**
      -  1005   -
            * Adds an entry to the specified collection and sets the Integer (e.g. the count) to 1. If the entry already exists in the
      -  1006   -
            * collection then the Integer is incremented by 1.
      +
                   Map<String, Integer> vendor, Map<String, Integer> product) {
      +  1004  12
               for (ClassNameInformation entry : classNames) {
      +  1005  3070
                   final List<String> list = entry.getPackageStructure();
      +  1006  3070
                   addEntry(vendor, list.get(0));
       1007   -
            *
      -  1008   -
            * @param collection a collection of strings and their occurrence count
      -  1009   -
            * @param key the key to add to the collection
      +
       
      +  1008  3070
                   if (list.size() == 2) {
      +  1009  0
                       addEntry(product, list.get(1));
       1010   -
            */
      -  1011   -
           private void addEntry(Map<String, Integer> collection, String key) {
      -  1012  8520
               if (collection.containsKey(key)) {
      -  1013  7487
                   collection.put(key, collection.get(key) + 1);
      -  1014   -
               } else {
      -  1015  1033
                   collection.put(key, 1);
      -  1016   -
               }
      -  1017  8520
           }
      -  1018   -
       
      -  1019   -
           /**
      -  1020   -
            * Cycles through the collection of class name information to see if parts of the package names are contained in the provided
      -  1021   -
            * value. If found, it will be added as the HIGHEST confidence evidence because we have more then one source corroborating the
      +
                   }
      +  1011  3070
                   if (list.size() == 3) {
      +  1012  690
                       addEntry(vendor, list.get(1));
      +  1013  690
                       addEntry(product, list.get(1));
      +  1014  690
                       addEntry(product, list.get(2));
      +  1015   +
                   }
      +  1016  3070
                   if (list.size() >= 4) {
      +  1017  2380
                       addEntry(vendor, list.get(1));
      +  1018  2380
                       addEntry(vendor, list.get(2));
      +  1019  2380
                       addEntry(product, list.get(1));
      +  1020  2380
                       addEntry(product, list.get(2));
      +  1021  2380
                       addEntry(product, list.get(3));
       1022   -
            * value.
      -  1023   -
            *
      -  1024   -
            * @param classes a collection of class name information
      +
                   }
      +  1023  3070
               }
      +  1024  12
           }
       1025   -
            * @param value the value to check to see if it contains a package name
      +
       
       1026   -
            * @param evidence the evidence collection to add new entries too
      +
           /**
       1027   -
            */
      +
            * Adds an entry to the specified collection and sets the Integer (e.g. the
       1028   -
           private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) {
      -  1029  55
               if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) {
      -  1030  13
                   return;
      +
            * count) to 1. If the entry already exists in the collection then the
      +  1029   +
            * Integer is incremented by 1.
      +  1030   +
            *
       1031   -
               }
      -  1032  42
               final String text = value.toLowerCase();
      -  1033  42
               for (ClassNameInformation cni : classes) {
      -  1034  16322
                   for (String key : cni.getPackageStructure()) {
      -  1035  62418
                       final Pattern p = Pattern.compile("\b" + key + "\b");
      -  1036  62418
                       if (p.matcher(text).find()) {
      +
            * @param collection a collection of strings and their occurrence count
      +  1032   +
            * @param key the key to add to the collection
      +  1033   +
            */
      +  1034   +
           private void addEntry(Map<String, Integer> collection, String key) {
      +  1035  17040
               if (collection.containsKey(key)) {
      +  1036  14974
                   collection.put(key, collection.get(key) + 1);
       1037   -
                           //if (text.contains(key)) { //note, package structure elements are already lowercase.
      -  1038  0
                           evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST);
      +
               } else {
      +  1038  2066
                   collection.put(key, 1);
       1039   -
                       }
      -  1040  62418
                   }
      -  1041  16322
               }
      -  1042  42
           }
      +
               }
      +  1040  17040
           }
      +  1041   +
       
      +  1042   +
           /**
       1043   -
       
      +
            * Cycles through the collection of class name information to see if parts
       1044   -
           /**
      +
            * of the package names are contained in the provided value. If found, it
       1045   -
            * Simple check to see if the attribute from a manifest is just a package name.
      +
            * will be added as the HIGHEST confidence evidence because we have more
       1046   -
            *
      +
            * then one source corroborating the value.
       1047   -
            * @param key the key of the value to check
      +
            *
       1048   -
            * @param value the value to check
      +
            * @param classes a collection of class name information
       1049   -
            * @return true if the value looks like a java package name, otherwise false
      +
            * @param value the value to check to see if it contains a package name
       1050   -
            */
      +
            * @param evidence the evidence collection to add new entries too
       1051   -
           private boolean isPackage(String key, String value) {
      +
            */
       1052   -
       
      -  1053  14
               return !key.matches(".*(version|title|vendor|name|license|description).*")
      -  1054  8
                       && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$");
      +
           private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) {
      +  1053  126
               if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) {
      +  1054  42
                   return;
       1055   -
       
      -  1056   -
           }
      -  1057   -
       
      -  1058   -
           /**
      -  1059   -
            * Extracts the license information from the pom and adds it to the dependency.
      -  1060   -
            *
      +
               }
      +  1056  84
               final String text = value.toLowerCase();
      +  1057  84
               for (ClassNameInformation cni : classes) {
      +  1058  32644
                   for (String key : cni.getPackageStructure()) {
      +  1059  124836
                       final Pattern p = Pattern.compile("\b" + key + "\b");
      +  1060  124836
                       if (p.matcher(text).find()) {
       1061   -
            * @param pom the pom object
      -  1062   -
            * @param dependency the dependency to add license information too
      +
                           //if (text.contains(key)) { //note, package structure elements are already lowercase.
      +  1062  0
                           evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST);
       1063   -
            */
      -  1064   -
           public static void extractLicense(Model pom, Dependency dependency) {
      -  1065   -
               //license
      -  1066  1
               if (pom.getLicenses() != null) {
      -  1067  1
                   String license = null;
      -  1068  1
                   for (License lic : pom.getLicenses()) {
      -  1069  0
                       String tmp = null;
      -  1070  0
                       if (lic.getName() != null) {
      -  1071  0
                           tmp = lic.getName();
      -  1072  
                       }
      -  1073  0
                       if (lic.getUrl() != null) {
      -  1074  0
                           if (tmp == null) {
      -  1075  0
                               tmp = lic.getUrl();
      -  1076   -
                           } else {
      -  1077  0
                               tmp += ": " + lic.getUrl();
      -  1078   -
                           }
      -  1079   -
                       }
      -  1080  0
                       if (tmp == null) {
      -  1081  0
                           continue;
      -  1082   -
                       }
      -  1083  0
                       if (HTML_DETECTION_PATTERN.matcher(tmp).find()) {
      -  1084  0
                           tmp = Jsoup.parse(tmp).text();
      -  1085   -
                       }
      -  1086  0
                       if (license == null) {
      -  1087  0
                           license = tmp;
      -  1088   -
                       } else {
      -  1089  0
                           license += "\n" + tmp;
      -  1090   -
                       }
      -  1091  0
                   }
      -  1092  1
                   if (license != null) {
      -  1093  0
                       dependency.setLicense(license);
      -  1094   +  1064  124836
                   }
      +  1065  32644
               }
      +  1066  84
           }
      +  1067  
       
      -  1095   -
                   }
      -  1096   -
               }
      -  1097  1
           }
      -  1098   -
       
      -  1099   +  1068  
           /**
      -  1100   -
            * Stores information about a class name.
      -  1101   -
            */
      -  1102   -
           protected static class ClassNameInformation {
      -  1103   -
       
      -  1104   -
               /**
      -  1105   -
                * <p>
      -  1106   -
                * Stores information about a given class name. This class will keep the fully qualified class name and a list of the
      -  1107   -
                * important parts of the package structure. Up to the first four levels of the package structure are stored, excluding a
      -  1108   -
                * leading "org" or "com". Example:</p>
      -  1109   -
                * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer");
      -  1110   -
                * System.out.println(obj.getName());
      -  1111   -
                * for (String p : obj.getPackageStructure())
      -  1112   -
                *     System.out.println(p);
      -  1113   -
                * </code>
      -  1114   -
                * <p>
      -  1115   -
                * Would result in:</p>
      -  1116   -
                * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer
      -  1117   -
                * owasp
      -  1118   -
                * dependencycheck
      -  1119   -
                * analyzer
      -  1120   -
                * jaranalyzer</code>
      -  1121   -
                *
      -  1122   -
                * @param className a fully qualified class name
      -  1123   -
                */
      -  1124  1535
               ClassNameInformation(String className) {
      -  1125  1535
                   name = className;
      -  1126  1535
                   if (name.contains("/")) {
      -  1127  1535
                       final String[] tmp = className.toLowerCase().split("/");
      -  1128  1535
                       int start = 0;
      -  1129  1535
                       int end = 3;
      -  1130  1535
                       if ("com".equals(tmp[0]) || "org".equals(tmp[0])) {
      -  1131  1535
                           start = 1;
      -  1132  1535
                           end = 4;
      -  1133   -
                       }
      -  1134  1535
                       if (tmp.length <= end) {
      -  1135  345
                           end = tmp.length - 1;
      -  1136   -
                       }
      -  1137  7330
                       for (int i = start; i <= end; i++) {
      -  1138  5795
                           packageStructure.add(tmp[i]);
      -  1139   -
                       }
      -  1140  1535
                   } else {
      -  1141  0
                       packageStructure.add(name);
      -  1142   -
                   }
      -  1143  1535
               }
      -  1144   -
               /**
      -  1145   -
                * The fully qualified class name.
      -  1146   -
                */
      -  1147   -
               private String name;
      -  1148   -
       
      -  1149   -
               /**
      -  1150   -
                * Get the value of name
      -  1151   -
                *
      -  1152   -
                * @return the value of name
      -  1153   -
                */
      -  1154   -
               public String getName() {
      -  1155  0
                   return name;
      -  1156   -
               }
      -  1157   -
       
      -  1158   -
               /**
      -  1159   -
                * Set the value of name
      -  1160   -
                *
      -  1161   -
                * @param name new value of name
      -  1162   -
                */
      -  1163   -
               public void setName(String name) {
      -  1164  0
                   this.name = name;
      -  1165  0
               }
      -  1166   -
               /**
      -  1167   -
                * Up to the first four levels of the package structure, excluding a leading "org" or "com".
      -  1168   -
                */
      -  1169  1535
               private final ArrayList<String> packageStructure = new ArrayList<String>();
      -  1170   -
       
      -  1171   -
               /**
      -  1172   -
                * Get the value of packageStructure
      -  1173   -
                *
      -  1174   -
                * @return the value of packageStructure
      -  1175   -
                */
      -  1176   -
               public ArrayList<String> getPackageStructure() {
      -  1177  17857
                   return packageStructure;
      -  1178   -
               }
      -  1179   -
           }
      -  1180   -
       
      -  1181   -
           /**
      -  1182   -
            * Retrieves the next temporary directory to extract an archive too.
      -  1183   +  1069   +
            * Simple check to see if the attribute from a manifest is just a package
      +  1070   +
            * name.
      +  1071  
            *
      -  1184   -
            * @return a directory
      -  1185   -
            * @throws AnalysisException thrown if unable to create temporary directory
      -  1186   +  1072   +
            * @param key the key of the value to check
      +  1073   +
            * @param value the value to check
      +  1074   +
            * @return true if the value looks like a java package name, otherwise false
      +  1075  
            */
      -  1187   -
           private File getNextTempDirectory() throws AnalysisException {
      -  1188  0
               dirCount += 1;
      -  1189  0
               final File directory = new File(tempFileLocation, String.valueOf(dirCount));
      -  1190   -
               //getting an exception for some directories not being able to be created; might be because the directory already exists?
      -  1191  0
               if (directory.exists()) {
      -  1192  0
                   return getNextTempDirectory();
      -  1193   -
               }
      -  1194  0
               if (!directory.mkdirs()) {
      -  1195  0
                   final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
      -  1196  0
                   throw new AnalysisException(msg);
      -  1197   -
               }
      -  1198  0
               return directory;
      -  1199   +  1076   +
           private boolean isPackage(String key, String value) {
      +  1077   +
       
      +  1078  56
               return !key.matches(".*(version|title|vendor|name|license|description).*")
      +  1079  16
                       && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$");
      +  1080   +
       
      +  1081  
           }
      +  1082   +
       
      +  1083   +
           /**
      +  1084   +
            * Extracts the license information from the pom and adds it to the
      +  1085   +
            * dependency.
      +  1086   +
            *
      +  1087   +
            * @param pom the pom object
      +  1088   +
            * @param dependency the dependency to add license information too
      +  1089   +
            */
      +  1090   +
           public static void extractLicense(Model pom, Dependency dependency) {
      +  1091   +
               //license
      +  1092  4
               if (pom.getLicenses() != null) {
      +  1093  4
                   String license = null;
      +  1094  4
                   for (License lic : pom.getLicenses()) {
      +  1095  0
                       String tmp = null;
      +  1096  0
                       if (lic.getName() != null) {
      +  1097  0
                           tmp = lic.getName();
      +  1098   +
                       }
      +  1099  0
                       if (lic.getUrl() != null) {
      +  1100  0
                           if (tmp == null) {
      +  1101  0
                               tmp = lic.getUrl();
      +  1102   +
                           } else {
      +  1103  0
                               tmp += ": " + lic.getUrl();
      +  1104   +
                           }
      +  1105   +
                       }
      +  1106  0
                       if (tmp == null) {
      +  1107  0
                           continue;
      +  1108   +
                       }
      +  1109  0
                       if (HTML_DETECTION_PATTERN.matcher(tmp).find()) {
      +  1110  0
                           tmp = Jsoup.parse(tmp).text();
      +  1111   +
                       }
      +  1112  0
                       if (license == null) {
      +  1113  0
                           license = tmp;
      +  1114   +
                       } else {
      +  1115  0
                           license += "\n" + tmp;
      +  1116   +
                       }
      +  1117  0
                   }
      +  1118  4
                   if (license != null) {
      +  1119  0
                       dependency.setLicense(license);
      +  1120   +
       
      +  1121   +
                   }
      +  1122   +
               }
      +  1123  4
           }
      +  1124   +
       
      +  1125   +
           /**
      +  1126   +
            * Stores information about a class name.
      +  1127   +
            */
      +  1128   +
           protected static class ClassNameInformation {
      +  1129   +
       
      +  1130   +
               /**
      +  1131   +
                * <p>
      +  1132   +
                * Stores information about a given class name. This class will keep the
      +  1133   +
                * fully qualified class name and a list of the important parts of the
      +  1134   +
                * package structure. Up to the first four levels of the package
      +  1135   +
                * structure are stored, excluding a leading "org" or "com".
      +  1136   +
                * Example:</p>
      +  1137   +
                * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer");
      +  1138   +
                * System.out.println(obj.getName());
      +  1139   +
                * for (String p : obj.getPackageStructure())
      +  1140   +
                *     System.out.println(p);
      +  1141   +
                * </code>
      +  1142   +
                * <p>
      +  1143   +
                * Would result in:</p>
      +  1144   +
                * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer
      +  1145   +
                * owasp
      +  1146   +
                * dependencycheck
      +  1147   +
                * analyzer
      +  1148   +
                * jaranalyzer</code>
      +  1149   +
                *
      +  1150   +
                * @param className a fully qualified class name
      +  1151   +
                */
      +  1152  3070
               ClassNameInformation(String className) {
      +  1153  3070
                   name = className;
      +  1154  3070
                   if (name.contains("/")) {
      +  1155  3070
                       final String[] tmp = className.toLowerCase().split("/");
      +  1156  3070
                       int start = 0;
      +  1157  3070
                       int end = 3;
      +  1158  3070
                       if ("com".equals(tmp[0]) || "org".equals(tmp[0])) {
      +  1159  3070
                           start = 1;
      +  1160  3070
                           end = 4;
      +  1161   +
                       }
      +  1162  3070
                       if (tmp.length <= end) {
      +  1163  690
                           end = tmp.length - 1;
      +  1164   +
                       }
      +  1165  14660
                       for (int i = start; i <= end; i++) {
      +  1166  11590
                           packageStructure.add(tmp[i]);
      +  1167   +
                       }
      +  1168  3070
                   } else {
      +  1169  0
                       packageStructure.add(name);
      +  1170   +
                   }
      +  1171  3070
               }
      +  1172   +
               /**
      +  1173   +
                * The fully qualified class name.
      +  1174   +
                */
      +  1175   +
               private String name;
      +  1176   +
       
      +  1177   +
               /**
      +  1178   +
                * Get the value of name
      +  1179   +
                *
      +  1180   +
                * @return the value of name
      +  1181   +
                */
      +  1182   +
               public String getName() {
      +  1183  0
                   return name;
      +  1184   +
               }
      +  1185   +
       
      +  1186   +
               /**
      +  1187   +
                * Set the value of name
      +  1188   +
                *
      +  1189   +
                * @param name new value of name
      +  1190   +
                */
      +  1191   +
               public void setName(String name) {
      +  1192  0
                   this.name = name;
      +  1193  0
               }
      +  1194   +
               /**
      +  1195   +
                * Up to the first four levels of the package structure, excluding a
      +  1196   +
                * leading "org" or "com".
      +  1197   +
                */
      +  1198  3070
               private final ArrayList<String> packageStructure = new ArrayList<String>();
      +  1199   +
       
       1200   +
               /**
      +  1201   +
                * Get the value of packageStructure
      +  1202   +
                *
      +  1203   +
                * @return the value of packageStructure
      +  1204   +
                */
      +  1205   +
               public ArrayList<String> getPackageStructure() {
      +  1206  35714
                   return packageStructure;
      +  1207   +
               }
      +  1208   +
           }
      +  1209   +
       
      +  1210   +
           /**
      +  1211   +
            * Retrieves the next temporary directory to extract an archive too.
      +  1212   +
            *
      +  1213   +
            * @return a directory
      +  1214   +
            * @throws AnalysisException thrown if unable to create temporary directory
      +  1215   +
            */
      +  1216   +
           private File getNextTempDirectory() throws AnalysisException {
      +  1217  0
               dirCount += 1;
      +  1218  0
               final File directory = new File(tempFileLocation, String.valueOf(dirCount));
      +  1219   +
               //getting an exception for some directories not being able to be created; might be because the directory already exists?
      +  1220  0
               if (directory.exists()) {
      +  1221  0
                   return getNextTempDirectory();
      +  1222   +
               }
      +  1223  0
               if (!directory.mkdirs()) {
      +  1224  0
                   final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
      +  1225  0
                   throw new AnalysisException(msg);
      +  1226   +
               }
      +  1227  0
               return directory;
      +  1228   +
           }
      +  1229  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html index 3cb4a599d..a17bba47e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html @@ -131,7 +131,7 @@
        * @author colezlaw
       57  
        */
      -  58  4
       public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
      +  58  12
       public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
       59  
       
       60   @@ -150,7 +150,7 @@
            * The logger.
       67  
            */
      -  68  1
           private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class);
      +  68  2
           private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class);
       69  
       
       70   @@ -169,7 +169,7 @@
            * The phase in which the analyzer runs.
       77  
            */
      -  78  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  78  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       79  
       
       80   @@ -198,7 +198,7 @@
            * Field indicating if the analyzer is enabled.
       92  
            */
      -  93  4
           private final boolean enabled = checkEnabled();
      +  93  12
           private final boolean enabled = checkEnabled();
       94  
       
       95   @@ -221,24 +221,24 @@
                central one) and it's enabled by the user.
       104  
                */
      -  105  4
               boolean retval = false;
      +  105  12
               boolean retval = false;
       106  
               try {
      -  107  4
                   if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))
      +  107  12
                   if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))
       108  0
                           && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) {
       109  0
                       LOGGER.info("Enabling Nexus analyzer");
       110  0
                       retval = true;
       111  
                   } else {
      -  112  4
                       LOGGER.debug("Nexus analyzer disabled, using Central instead");
      +  112  12
                       LOGGER.debug("Nexus analyzer disabled, using Central instead");
       113  
                   }
       114  0
               } catch (InvalidSettingException ise) {
       115  0
                   LOGGER.warn("Invalid setting. Disabling Nexus analyzer");
      -  116  4
               }
      +  116  12
               }
       117  
       
      -  118  4
               return retval;
      +  118  12
               return retval;
       119  
           }
       120   @@ -316,7 +316,7 @@
           @Override
       164  
           public String getName() {
      -  165  4
               return ANALYZER_NAME;
      +  165  32
               return ANALYZER_NAME;
       166  
           }
       167   @@ -335,7 +335,7 @@
           @Override
       174  
           protected String getAnalyzerEnabledSettingKey() {
      -  175  4
               return Settings.KEYS.ANALYZER_NEXUS_ENABLED;
      +  175  12
               return Settings.KEYS.ANALYZER_NEXUS_ENABLED;
       176  
           }
       177   @@ -354,7 +354,7 @@
           @Override
       184  
           public AnalysisPhase getAnalysisPhase() {
      -  185  3
               return ANALYSIS_PHASE;
      +  185  8
               return ANALYSIS_PHASE;
       186  
           }
       187   @@ -365,7 +365,7 @@
            * The file filter used to determine which files this analyzer supports.
       190  
            */
      -  191  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
      +  191  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
       192  
       
       193   @@ -382,7 +382,7 @@
           @Override
       199  
           protected FileFilter getFileFilter() {
      -  200  853
               return FILTER;
      +  200  1718
               return FILTER;
       201  
           }
       202   @@ -469,6 +469,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NodePackageAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NodePackageAnalyzer.html index 2eae5525a..7c9c26792 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NodePackageAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NodePackageAnalyzer.html @@ -111,235 +111,237 @@
        * @author Dale Visser
       47  
        */
      -  48  7
       public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
      -  49   -
       
      +  48   +
       @Experimental
      +  49  18
       public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
       50   -
           /**
      +
       
       51   -
            * The logger.
      +
           /**
       52   +
            * The logger.
      +  53  
            */
      -  53  1
           private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class);
      -  54   -
       
      +  54  2
           private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class);
       55   -
           /**
      +
       
       56   -
            * The name of the analyzer.
      +
           /**
       57   -
            */
      +
            * The name of the analyzer.
       58   -
           private static final String ANALYZER_NAME = "Node.js Package Analyzer";
      +
            */
       59   -
       
      +
           private static final String ANALYZER_NAME = "Node.js Package Analyzer";
       60   -
           /**
      +
       
       61   -
            * The phase that this analyzer is intended to run in.
      +
           /**
       62   +
            * The phase that this analyzer is intended to run in.
      +  63  
            */
      -  63  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      -  64   -
       
      +  64  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       65   -
           /**
      +
       
       66   -
            * The file name to scan.
      +
           /**
       67   -
            */
      +
            * The file name to scan.
       68   -
           public static final String PACKAGE_JSON = "package.json";
      +
            */
       69   -
           /**
      +
           public static final String PACKAGE_JSON = "package.json";
       70   -
            * Filter that detects files named "package.json".
      +
           /**
       71   +
            * Filter that detects files named "package.json".
      +  72  
            */
      -  72  2
           private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance()
      -  73  1
                   .addFilenames(PACKAGE_JSON).build();
      -  74   -
       
      +  73  4
           private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance()
      +  74  2
                   .addFilenames(PACKAGE_JSON).build();
       75   -
           /**
      +
       
       76   -
            * Returns the FileFilter
      +
           /**
       77   -
            *
      +
            * Returns the FileFilter
       78   -
            * @return the FileFilter
      +
            *
       79   -
            */
      +
            * @return the FileFilter
       80   -
           @Override
      +
            */
       81   +
           @Override
      +  82  
           protected FileFilter getFileFilter() {
      -  82  854
               return PACKAGE_JSON_FILTER;
      -  83   -
           }
      +  83  1720
               return PACKAGE_JSON_FILTER;
       84   -
       
      +
           }
       85   -
           @Override
      +
       
       86   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      +
           @Override
       87   +
           protected void initializeFileTypeAnalyzer() throws Exception {
      +  88  
               // NO-OP
      -  88  3
           }
      -  89   -
       
      +  89  6
           }
       90   -
           /**
      +
       
       91   -
            * Returns the name of the analyzer.
      +
           /**
       92   -
            *
      +
            * Returns the name of the analyzer.
       93   -
            * @return the name of the analyzer.
      +
            *
       94   -
            */
      +
            * @return the name of the analyzer.
       95   -
           @Override
      +
            */
       96   +
           @Override
      +  97  
           public String getName() {
      -  97  5
               return ANALYZER_NAME;
      -  98   -
           }
      +  98  30
               return ANALYZER_NAME;
       99   -
       
      +
           }
       100   -
           /**
      +
       
       101   -
            * Returns the phase that the analyzer is intended to run in.
      +
           /**
       102   -
            *
      +
            * Returns the phase that the analyzer is intended to run in.
       103   -
            * @return the phase that the analyzer is intended to run in.
      +
            *
       104   -
            */
      +
            * @return the phase that the analyzer is intended to run in.
       105   -
           @Override
      +
            */
       106   +
           @Override
      +  107  
           public AnalysisPhase getAnalysisPhase() {
      -  107  3
               return ANALYSIS_PHASE;
      -  108   -
           }
      +  108  8
               return ANALYSIS_PHASE;
       109   -
       
      -  110   -
           /**
      -  111   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      -  112   -
            *
      -  113   -
            * @return the analyzer's enabled property setting key
      -  114   -
            */
      -  115   -
           @Override
      -  116   -
           protected String getAnalyzerEnabledSettingKey() {
      -  117  7
               return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED;
      -  118  
           }
      -  119   +  110  
       
      -  120   -
           @Override
      -  121   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  122   -
                   throws AnalysisException {
      -  123  1
               final File file = dependency.getActualFile();
      -  124   -
               JsonReader jsonReader;
      -  125   -
               try {
      -  126  1
                   jsonReader = Json.createReader(FileUtils.openInputStream(file));
      -  127  0
               } catch (IOException e) {
      -  128  0
                   throw new AnalysisException(
      -  129   -
                           "Problem occurred while reading dependency file.", e);
      -  130  1
               }
      -  131   -
               try {
      -  132  1
                   final JsonObject json = jsonReader.readObject();
      -  133  1
                   final EvidenceCollection productEvidence = dependency.getProductEvidence();
      -  134  1
                   final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
      -  135  1
                   if (json.containsKey("name")) {
      -  136  1
                       final Object value = json.get("name");
      -  137  1
                       if (value instanceof JsonString) {
      -  138  1
                           final String valueString = ((JsonString) value).getString();
      -  139  1
                           productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST);
      -  140  1
                           vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW);
      -  141  1
                       } else {
      -  142  0
                           LOGGER.warn("JSON value not string as expected: {}", value);
      -  143   -
                       }
      -  144   -
                   }
      -  145  1
                   addToEvidence(json, productEvidence, "description");
      -  146  1
                   addToEvidence(json, vendorEvidence, "author");
      -  147  1
                   addToEvidence(json, dependency.getVersionEvidence(), "version");
      -  148  1
                   dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
      -  149  0
               } catch (JsonException e) {
      -  150  0
                   LOGGER.warn("Failed to parse package.json file.", e);
      -  151   -
               } finally {
      -  152  1
                   jsonReader.close();
      -  153  1
               }
      -  154  1
           }
      -  155   -
       
      -  156   +  111  
           /**
      -  157   -
            * Adds information to an evidence collection from the node json configuration.
      -  158   +  112   +
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +  113  
            *
      -  159   -
            * @param json information from node.js
      -  160   -
            * @param collection a set of evidence about a dependency
      -  161   -
            * @param key the key to obtain the data from the json information
      -  162   +  114   +
            * @return the analyzer's enabled property setting key
      +  115  
            */
      -  163   -
           private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) {
      -  164  3
               if (json.containsKey(key)) {
      -  165  3
                   final JsonValue value = json.get(key);
      -  166  3
                   if (value instanceof JsonString) {
      -  167  2
                       collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST);
      -  168  1
                   } else if (value instanceof JsonObject) {
      -  169  1
                       final JsonObject jsonObject = (JsonObject) value;
      -  170  1
                       for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
      -  171  1
                           final String property = entry.getKey();
      -  172  1
                           final JsonValue subValue = entry.getValue();
      -  173  1
                           if (subValue instanceof JsonString) {
      -  174  2
                               collection.addEvidence(PACKAGE_JSON,
      -  175  1
                                       String.format("%s.%s", key, property),
      -  176  1
                                       ((JsonString) subValue).getString(),
      -  177   -
                                       Confidence.HIGHEST);
      -  178   -
                           } else {
      -  179  0
                               LOGGER.warn("JSON sub-value not string as expected: {}", subValue);
      -  180   -
                           }
      -  181  1
                       }
      -  182  1
                   } else {
      -  183  0
                       LOGGER.warn("JSON value not string or JSON object as expected: {}", value);
      -  184   +  116   +
           @Override
      +  117   +
           protected String getAnalyzerEnabledSettingKey() {
      +  118  18
               return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED;
      +  119   +
           }
      +  120   +
       
      +  121   +
           @Override
      +  122   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  123   +
                   throws AnalysisException {
      +  124  2
               final File file = dependency.getActualFile();
      +  125   +
               JsonReader jsonReader;
      +  126   +
               try {
      +  127  2
                   jsonReader = Json.createReader(FileUtils.openInputStream(file));
      +  128  0
               } catch (IOException e) {
      +  129  0
                   throw new AnalysisException(
      +  130   +
                           "Problem occurred while reading dependency file.", e);
      +  131  2
               }
      +  132   +
               try {
      +  133  2
                   final JsonObject json = jsonReader.readObject();
      +  134  2
                   final EvidenceCollection productEvidence = dependency.getProductEvidence();
      +  135  2
                   final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
      +  136  2
                   if (json.containsKey("name")) {
      +  137  2
                       final Object value = json.get("name");
      +  138  2
                       if (value instanceof JsonString) {
      +  139  2
                           final String valueString = ((JsonString) value).getString();
      +  140  2
                           productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST);
      +  141  2
                           vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW);
      +  142  2
                       } else {
      +  143  0
                           LOGGER.warn("JSON value not string as expected: {}", value);
      +  144   +
                       }
      +  145  
                   }
      +  146  2
                   addToEvidence(json, productEvidence, "description");
      +  147  2
                   addToEvidence(json, vendorEvidence, "author");
      +  148  2
                   addToEvidence(json, dependency.getVersionEvidence(), "version");
      +  149  2
                   dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
      +  150  0
               } catch (JsonException e) {
      +  151  0
                   LOGGER.warn("Failed to parse package.json file.", e);
      +  152   +
               } finally {
      +  153  2
                   jsonReader.close();
      +  154  2
               }
      +  155  2
           }
      +  156   +
       
      +  157   +
           /**
      +  158   +
            * Adds information to an evidence collection from the node json configuration.
      +  159   +
            *
      +  160   +
            * @param json information from node.js
      +  161   +
            * @param collection a set of evidence about a dependency
      +  162   +
            * @param key the key to obtain the data from the json information
      +  163   +
            */
      +  164   +
           private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) {
      +  165  6
               if (json.containsKey(key)) {
      +  166  6
                   final JsonValue value = json.get(key);
      +  167  6
                   if (value instanceof JsonString) {
      +  168  4
                       collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST);
      +  169  2
                   } else if (value instanceof JsonObject) {
      +  170  2
                       final JsonObject jsonObject = (JsonObject) value;
      +  171  2
                       for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
      +  172  2
                           final String property = entry.getKey();
      +  173  2
                           final JsonValue subValue = entry.getValue();
      +  174  2
                           if (subValue instanceof JsonString) {
      +  175  4
                               collection.addEvidence(PACKAGE_JSON,
      +  176  2
                                       String.format("%s.%s", key, property),
      +  177  2
                                       ((JsonString) subValue).getString(),
      +  178   +
                                       Confidence.HIGHEST);
      +  179   +
                           } else {
      +  180  0
                               LOGGER.warn("JSON sub-value not string as expected: {}", subValue);
      +  181   +
                           }
      +  182  2
                       }
      +  183  2
                   } else {
      +  184  0
                       LOGGER.warn("JSON value not string or JSON object as expected: {}", value);
       185   +
                   }
      +  186  
               }
      -  186  3
           }
      -  187   +  187  6
           }
      +  188  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html index 0beb970d6..46161c9fa 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html @@ -101,7 +101,7 @@
        * @author colezlaw
       42  
        */
      -  43  7
       public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
      +  43  18
       public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
       44  
       
       45   @@ -110,7 +110,7 @@
            * The logger.
       47  
            */
      -  48  1
           private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class);
      +  48  2
           private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class);
       49  
       
       50   @@ -129,7 +129,7 @@
            * The phase in which the analyzer runs.
       57  
            */
      -  58  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  58  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       59  
       
       60   @@ -173,7 +173,7 @@
           @Override
       80  
           public String getName() {
      -  81  5
               return ANALYZER_NAME;
      +  81  34
               return ANALYZER_NAME;
       82  
           }
       83   @@ -192,7 +192,7 @@
           @Override
       90  
           protected String getAnalyzerEnabledSettingKey() {
      -  91  7
               return Settings.KEYS.ANALYZER_NUSPEC_ENABLED;
      +  91  18
               return Settings.KEYS.ANALYZER_NUSPEC_ENABLED;
       92  
           }
       93   @@ -211,7 +211,7 @@
           @Override
       100  
           public AnalysisPhase getAnalysisPhase() {
      -  101  4
               return ANALYSIS_PHASE;
      +  101  10
               return ANALYSIS_PHASE;
       102  
           }
       103   @@ -222,8 +222,8 @@
            * The file filter used to determine which files this analyzer supports.
       106  
            */
      -  107  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
      -  108  1
                   SUPPORTED_EXTENSIONS).build();
      +  107  4
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
      +  108  2
                   SUPPORTED_EXTENSIONS).build();
       109  
       
       110   @@ -240,7 +240,7 @@
           @Override
       116  
           protected FileFilter getFileFilter() {
      -  117  855
               return FILTER;
      +  117  1722
               return FILTER;
       118  
           }
       119   @@ -311,6 +311,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NvdCveAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NvdCveAnalyzer.html index 231918aff..1a48141ae 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NvdCveAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NvdCveAnalyzer.html @@ -89,7 +89,7 @@
        * @author Jeremy Long
       36  
        */
      -  37  4
       public class NvdCveAnalyzer implements Analyzer {
      +  37  12
       public class NvdCveAnalyzer implements Analyzer {
       38  
       
       39   @@ -128,9 +128,9 @@
            */
       56  
           public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException {
      -  57  1
               cveDB = new CveDB();
      -  58  1
               cveDB.open();
      -  59  1
           }
      +  57  4
               cveDB = new CveDB();
      +  58  4
               cveDB.open();
      +  59  4
           }
       60  
       
       61   @@ -143,9 +143,9 @@
           @Override
       65  
           public void close() {
      -  66  1
               cveDB.close();
      -  67  1
               cveDB = null;
      -  68  1
           }
      +  66  4
               cveDB.close();
      +  67  4
               cveDB = null;
      +  68  4
           }
       69  
       
       70   @@ -160,7 +160,7 @@
            */
       75  
           public boolean isOpen() {
      -  76  3
               return cveDB != null;
      +  76  12
               return cveDB != null;
       77  
           }
       78   @@ -179,12 +179,12 @@
           @Override
       85  
           protected void finalize() throws Throwable {
      -  86  3
               super.finalize();
      -  87  3
               if (isOpen()) {
      +  86  12
               super.finalize();
      +  87  12
               if (isOpen()) {
       88  0
                   close();
       89  
               }
      -  90  3
           }
      +  90  12
           }
       91  
       
       92   @@ -205,20 +205,20 @@
           @Override
       100  
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      -  101  2
               for (Identifier id : dependency.getIdentifiers()) {
      -  102  3
                   if ("cpe".equals(id.getType())) {
      +  101  8
               for (Identifier id : dependency.getIdentifiers()) {
      +  102  6
                   if ("cpe".equals(id.getType())) {
       103  
                       try {
      -  104  3
                           final String value = id.getValue();
      -  105  3
                           final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
      -  106  3
                           dependency.getVulnerabilities().addAll(vulns);
      +  104  6
                           final String value = id.getValue();
      +  105  6
                           final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
      +  106  6
                           dependency.getVulnerabilities().addAll(vulns);
       107  0
                       } catch (DatabaseException ex) {
       108  0
                           throw new AnalysisException(ex);
      -  109  3
                       }
      +  109  6
                       }
       110  
                   }
      -  111  3
               }
      -  112  2
               for (Identifier id : dependency.getSuppressedIdentifiers()) {
      +  111  6
               }
      +  112  8
               for (Identifier id : dependency.getSuppressedIdentifiers()) {
       113  0
                   if ("cpe".equals(id.getType())) {
       114  
                       try {
      @@ -231,7 +231,7 @@  121  
                   }
       122  0
               }
      -  123  2
           }
      +  123  8
           }
       124  
       
       125   @@ -248,7 +248,7 @@
           @Override
       131  
           public String getName() {
      -  132  4
               return "NVD CVE Analyzer";
      +  132  32
               return "NVD CVE Analyzer";
       133  
           }
       134   @@ -267,7 +267,7 @@
           @Override
       141  
           public AnalysisPhase getAnalysisPhase() {
      -  142  3
               return AnalysisPhase.FINDING_ANALYSIS;
      +  142  8
               return AnalysisPhase.FINDING_ANALYSIS;
       143  
           }
       144   @@ -286,12 +286,12 @@
           @Override
       151  
           public void initialize() throws Exception {
      -  152  1
               this.open();
      -  153  1
           }
      +  152  4
               this.open();
      +  153  4
           }
       154  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html index c077c5f25..be27a36bd 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      OpenSSLAnalyzer
      91%
      34/37
      71%
      10/14
      2.125
      OpenSSLAnalyzer
      91%
      32/35
      71%
      10/14
      2.25
       
      @@ -78,260 +78,338 @@  30  
       import java.io.IOException;
       31   -
       import java.util.regex.Matcher;
      +
       import java.nio.charset.Charset;
       32   -
       import java.util.regex.Pattern;
      +
       import java.util.regex.Matcher;
       33   -
       
      +
       import java.util.regex.Pattern;
       34   -
       /**
      -  35   -
        * Used to analyze OpenSSL source code present in the file system.
      -  36   -
        *
      -  37   -
        * @author Dale Visser
      -  38   -
        */
      -  39  8
       public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer {
      -  40  
       
      +  35   +
       /**
      +  36   +
        * Used to analyze OpenSSL source code present in the file system.
      +  37   +
        *
      +  38   +
        * @author Dale Visser
      +  39   +
        */
      +  40  20
       public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer {
       41   -
           private static final int HEXADECIMAL = 16;
      +
       
       42  
           /**
       43   -
            * Filename to analyze. All other .h files get removed from consideration.
      +
            * Hexadecimal.
       44  
            */
       45   -
           private static final String OPENSSLV_H = "opensslv.h";
      +
           private static final int HEXADECIMAL = 16;
       46   -
       
      +
           /**
       47   -
           /**
      +
            * Filename to analyze. All other .h files get removed from consideration.
       48   -
            * Filter that detects files named "__init__.py".
      +
            */
       49   -
            */
      -  50  1
           private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build();
      -  51  1
           private static final Pattern VERSION_PATTERN = Pattern.compile(
      -  52   -
                   "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL
      -  53   -
                   | Pattern.CASE_INSENSITIVE);
      -  54   -
           private static final int MAJOR_OFFSET = 28;
      -  55   -
           private static final long MINOR_MASK = 0x0ff00000L;
      -  56   -
           private static final int MINOR_OFFSET = 20;
      -  57   -
           private static final long FIX_MASK = 0x000ff000L;
      -  58   -
           private static final int FIX_OFFSET = 12;
      -  59   -
           private static final long PATCH_MASK = 0x00000ff0L;
      -  60   -
           private static final int PATCH_OFFSET = 4;
      -  61   -
           private static final int NUM_LETTERS = 26;
      -  62   -
           private static final int STATUS_MASK = 0x0000000f;
      -  63   +
           private static final String OPENSSLV_H = "opensslv.h";
      +  50  
       
      -  64   +  51  
           /**
      -  65   -
            * Returns the open SSL version as a string.
      -  66   -
            *
      -  67   -
            * @param openSSLVersionConstant The open SSL version
      -  68   -
            * @return the version of openssl
      -  69   +  52   +
            * Filter that detects files named "__init__.py".
      +  53  
            */
      +  54  2
           private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build();
      +  55   +
           /**
      +  56   +
            * Open SSL Version number pattern.
      +  57   +
            */
      +  58  2
           private static final Pattern VERSION_PATTERN = Pattern.compile(
      +  59   +
                   "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL
      +  60   +
                   | Pattern.CASE_INSENSITIVE);
      +  61   +
           /**
      +  62   +
            * The offset of the major version number.
      +  63   +
            */
      +  64   +
           private static final int MAJOR_OFFSET = 28;
      +  65   +
           /**
      +  66   +
            * The mask for the minor version number.
      +  67   +
            */
      +  68   +
           private static final long MINOR_MASK = 0x0ff00000L;
      +  69   +
           /**
       70   -
           static String getOpenSSLVersion(long openSSLVersionConstant) {
      -  71  9
               final long major = openSSLVersionConstant >>> MAJOR_OFFSET;
      -  72  9
               final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET;
      -  73  9
               final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET;
      -  74  9
               final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET;
      -  75  9
               final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1));
      -  76  9
               final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK);
      -  77  9
               final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode);
      -  78  9
               return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status);
      +
            * The offset of the minor version number.
      +  71   +
            */
      +  72   +
           private static final int MINOR_OFFSET = 20;
      +  73   +
           /**
      +  74   +
            * The max for the fix version.
      +  75   +
            */
      +  76   +
           private static final long FIX_MASK = 0x000ff000L;
      +  77   +
           /**
      +  78   +
            * The offset for the fix version.
       79   -
           }
      +
            */
       80   -
       
      +
           private static final int FIX_OFFSET = 12;
       81  
           /**
       82   -
            * Returns the name of the Python Package Analyzer.
      +
            * The mask for the patch version.
       83   -
            *
      -  84   -
            * @return the name of the analyzer
      -  85  
            */
      -  86   -
           @Override
      -  87   -
           public String getName() {
      -  88  5
               return "OpenSSL Source Analyzer";
      -  89   -
           }
      -  90   -
       
      -  91   +  84   +
           private static final long PATCH_MASK = 0x00000ff0L;
      +  85  
           /**
      +  86   +
            * The offset for the patch version.
      +  87   +
            */
      +  88   +
           private static final int PATCH_OFFSET = 4;
      +  89   +
           /**
      +  90   +
            * Number of letters.
      +  91   +
            */
       92   -
            * Tell that we are used for information collection.
      +
           private static final int NUM_LETTERS = 26;
       93   -
            *
      +
           /**
       94   -
            * @return INFORMATION_COLLECTION
      +
            * The status mask.
       95  
            */
       96   -
           @Override
      +
           private static final int STATUS_MASK = 0x0000000f;
       97   -
           public AnalysisPhase getAnalysisPhase() {
      -  98  3
               return AnalysisPhase.INFORMATION_COLLECTION;
      +
       
      +  98   +
           /**
       99   -
           }
      +
            * Returns the open SSL version as a string.
       100   -
       
      +
            *
       101   -
           /**
      +
            * @param openSSLVersionConstant The open SSL version
       102   -
            * Returns the set of supported file extensions.
      +
            * @return the version of openssl
       103   -
            *
      +
            */
       104   -
            * @return the set of supported file extensions
      -  105   -
            */
      -  106   -
           @Override
      -  107   -
           protected FileFilter getFileFilter() {
      -  108  854
               return OPENSSLV_FILTER;
      -  109   -
           }
      -  110   -
       
      -  111   -
           /**
      -  112   -
            * No-op initializer implementation.
      +
           static String getOpenSSLVersion(long openSSLVersionConstant) {
      +  105  18
               final long major = openSSLVersionConstant >>> MAJOR_OFFSET;
      +  106  18
               final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET;
      +  107  18
               final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET;
      +  108  18
               final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET;
      +  109  18
               final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1));
      +  110  18
               final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK);
      +  111  18
               final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode);
      +  112  18
               return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status);
       113   -
            *
      +
           }
       114   -
            * @throws Exception never thrown
      +
       
       115   -
            */
      +
           /**
       116   -
           @Override
      +
            * Returns the name of the Python Package Analyzer.
       117   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      +
            *
       118   -
               // Nothing to do here.
      -  119  4
           }
      +
            * @return the name of the analyzer
      +  119   +
            */
       120   -
       
      +
           @Override
       121   -
           /**
      -  122   -
            * Analyzes python packages and adds evidence to the dependency.
      +
           public String getName() {
      +  122  34
               return "OpenSSL Source Analyzer";
       123   -
            *
      +
           }
       124   -
            * @param dependency the dependency being analyzed
      +
       
       125   -
            * @param engine the engine being used to perform the scan
      -  126   -
            * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
      -  127   -
            */
      -  128   -
           @Override
      -  129   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  130   -
                   throws AnalysisException {
      -  131  1
               final File file = dependency.getActualFile();
      -  132  1
               final String parentName = file.getParentFile().getName();
      -  133  1
               boolean found = false;
      -  134  1
               final String contents = getFileContents(file);
      -  135  1
               if (!contents.isEmpty()) {
      -  136  1
                   final Matcher matcher = VERSION_PATTERN.matcher(contents);
      -  137  1
                   if (matcher.find()) {
      -  138  2
                       dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant",
      -  139  1
                               getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH);
      -  140  1
                       found = true;
      -  141   -
                   }
      -  142   -
               }
      -  143  1
               if (found) {
      -  144  1
                   dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H);
      -  145  1
                   dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST);
      -  146  1
                   dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST);
      -  147   -
               } else {
      -  148  0
                   engine.getDependencies().remove(dependency);
      -  149   -
               }
      -  150  1
           }
      -  151   -
       
      -  152  
           /**
      -  153   -
            * Retrieves the contents of a given file.
      -  154   +  126   +
            * Tell that we are used for information collection.
      +  127  
            *
      -  155   -
            * @param actualFile the file to read
      -  156   -
            * @return the contents of the file
      -  157   -
            * @throws AnalysisException thrown if there is an IO Exception
      -  158   +  128   +
            * @return INFORMATION_COLLECTION
      +  129  
            */
      -  159   -
           private String getFileContents(final File actualFile)
      -  160   -
                   throws AnalysisException {
      -  161   -
               String contents;
      -  162   -
               try {
      -  163  1
                   contents = FileUtils.readFileToString(actualFile).trim();
      -  164  0
               } catch (IOException e) {
      -  165  0
                   throw new AnalysisException(
      -  166   -
                           "Problem occurred while reading dependency file.", e);
      -  167  1
               }
      -  168  1
               return contents;
      -  169   -
           }
      -  170   -
       
      -  171   +  130  
           @Override
      -  172   -
           protected String getAnalyzerEnabledSettingKey() {
      -  173  8
               return Settings.KEYS.ANALYZER_OPENSSL_ENABLED;
      -  174   +  131   +
           public AnalysisPhase getAnalysisPhase() {
      +  132  8
               return AnalysisPhase.INFORMATION_COLLECTION;
      +  133  
           }
      -  175   +  134   +
       
      +  135   +
           /**
      +  136   +
            * Returns the set of supported file extensions.
      +  137   +
            *
      +  138   +
            * @return the set of supported file extensions
      +  139   +
            */
      +  140   +
           @Override
      +  141   +
           protected FileFilter getFileFilter() {
      +  142  1720
               return OPENSSLV_FILTER;
      +  143   +
           }
      +  144   +
       
      +  145   +
           /**
      +  146   +
            * No-op initializer implementation.
      +  147   +
            *
      +  148   +
            * @throws Exception never thrown
      +  149   +
            */
      +  150   +
           @Override
      +  151   +
           protected void initializeFileTypeAnalyzer() throws Exception {
      +  152   +
               // Nothing to do here.
      +  153  8
           }
      +  154   +
       
      +  155   +
           /**
      +  156   +
            * Analyzes python packages and adds evidence to the dependency.
      +  157   +
            *
      +  158   +
            * @param dependency the dependency being analyzed
      +  159   +
            * @param engine the engine being used to perform the scan
      +  160   +
            * @throws AnalysisException thrown if there is an unrecoverable error
      +  161   +
            * analyzing the dependency
      +  162   +
            */
      +  163   +
           @Override
      +  164   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  165   +
                   throws AnalysisException {
      +  166  2
               final File file = dependency.getActualFile();
      +  167  2
               final String parentName = file.getParentFile().getName();
      +  168  2
               boolean found = false;
      +  169  2
               final String contents = getFileContents(file);
      +  170  2
               if (!contents.isEmpty()) {
      +  171  2
                   final Matcher matcher = VERSION_PATTERN.matcher(contents);
      +  172  2
                   if (matcher.find()) {
      +  173  4
                       dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant",
      +  174  2
                               getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH);
      +  175  2
                       found = true;
      +  176   +
                   }
      +  177   +
               }
      +  178  2
               if (found) {
      +  179  2
                   dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H);
      +  180  2
                   dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST);
      +  181  2
                   dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST);
      +  182   +
               } else {
      +  183  0
                   engine.getDependencies().remove(dependency);
      +  184   +
               }
      +  185  2
           }
      +  186   +
       
      +  187   +
           /**
      +  188   +
            * Retrieves the contents of a given file.
      +  189   +
            *
      +  190   +
            * @param actualFile the file to read
      +  191   +
            * @return the contents of the file
      +  192   +
            * @throws AnalysisException thrown if there is an IO Exception
      +  193   +
            */
      +  194   +
           private String getFileContents(final File actualFile)
      +  195   +
                   throws AnalysisException {
      +  196   +
               try {
      +  197  2
                   return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim();
      +  198  0
               } catch (IOException e) {
      +  199  0
                   throw new AnalysisException(
      +  200   +
                           "Problem occurred while reading dependency file.", e);
      +  201   +
               }
      +  202   +
           }
      +  203   +
       
      +  204   +
           /**
      +  205   +
            * Returns the setting for the analyzer enabled setting key.
      +  206   +
            *
      +  207   +
            * @return the setting for the analyzer enabled setting key
      +  208   +
            */
      +  209   +
           @Override
      +  210   +
           protected String getAnalyzerEnabledSettingKey() {
      +  211  20
               return Settings.KEYS.ANALYZER_OPENSSL_ENABLED;
      +  212   +
           }
      +  213  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html index 998a88538..6492f3d42 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html @@ -121,548 +121,550 @@
        * @author Dale Visser
       52  
        */
      -  53  12
       public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
      -  54   -
       
      +  53   +
       @Experimental
      +  54  28
       public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
       55   -
           /**
      +
       
       56   -
            * Name of egg metadata files to analyze.
      +
           /**
       57   -
            */
      +
            * Name of egg metadata files to analyze.
       58   -
           private static final String PKG_INFO = "PKG-INFO";
      +
            */
       59   -
       
      +
           private static final String PKG_INFO = "PKG-INFO";
       60   -
           /**
      +
       
       61   -
            * Name of wheel metadata files to analyze.
      +
           /**
       62   -
            */
      +
            * Name of wheel metadata files to analyze.
       63   -
           private static final String METADATA = "METADATA";
      +
            */
       64   -
       
      +
           private static final String METADATA = "METADATA";
       65   -
           /**
      +
       
       66   -
            * The logger.
      +
           /**
       67   +
            * The logger.
      +  68  
            */
      -  68  1
           private static final Logger LOGGER = LoggerFactory
      -  69  1
                   .getLogger(PythonDistributionAnalyzer.class);
      -  70   -
       
      +  69  2
           private static final Logger LOGGER = LoggerFactory
      +  70  2
                   .getLogger(PythonDistributionAnalyzer.class);
       71   -
           /**
      +
       
       72   -
            * The count of directories created during analysis. This is used for creating temporary directories.
      +
           /**
       73   +
            * The count of directories created during analysis. This is used for creating temporary directories.
      +  74  
            */
      -  74  1
           private static int dirCount = 0;
      -  75   -
       
      +  75  2
           private static int dirCount = 0;
       76   -
           /**
      +
       
       77   -
            * The name of the analyzer.
      +
           /**
       78   -
            */
      +
            * The name of the analyzer.
       79   -
           private static final String ANALYZER_NAME = "Python Distribution Analyzer";
      +
            */
       80   -
           /**
      +
           private static final String ANALYZER_NAME = "Python Distribution Analyzer";
       81   -
            * The phase that this analyzer is intended to run in.
      +
           /**
       82   +
            * The phase that this analyzer is intended to run in.
      +  83  
            */
      -  83  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      -  84   -
       
      +  84  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       85   -
           /**
      +
       
       86   -
            * The set of file extensions supported by this analyzer.
      +
           /**
       87   +
            * The set of file extensions supported by this analyzer.
      +  88  
            */
      -  88  1
           private static final String[] EXTENSIONS = {"whl", "egg", "zip"};
      -  89   -
       
      +  89  2
           private static final String[] EXTENSIONS = {"whl", "egg", "zip"};
       90   -
           /**
      +
       
       91   -
            * Used to match on egg archive candidate extensions.
      +
           /**
       92   +
            * Used to match on egg archive candidate extensions.
      +  93  
            */
      -  93  1
           private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build();
      -  94   -
       
      +  94  2
           private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build();
       95   -
           /**
      +
       
       96   -
            * Used to detect files with a .whl extension.
      +
           /**
       97   +
            * Used to detect files with a .whl extension.
      +  98  
            */
      -  98  1
           private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build();
      -  99   -
       
      +  99  2
           private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build();
       100   -
           /**
      +
       
       101   -
            * The parent directory for the individual directories per archive.
      +
           /**
       102   -
            */
      +
            * The parent directory for the individual directories per archive.
       103   -
           private File tempFileLocation;
      +
            */
       104   -
       
      +
           private File tempFileLocation;
       105   -
           /**
      +
       
       106   -
            * Filter that detects *.dist-info files (but doesn't verify they are directories.
      +
           /**
       107   +
            * Filter that detects *.dist-info files (but doesn't verify they are directories.
      +  108  
            */
      -  108  1
           private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter(
      -  109   -
                   ".dist-info");
      +  109  2
           private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter(
       110   -
       
      +
                   ".dist-info");
       111   -
           /**
      +
       
       112   -
            * Filter that detects files named "METADATA".
      +
           /**
       113   -
            */
      -  114  1
           private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter(
      -  115   -
                   "EGG-INFO");
      -  116   -
       
      -  117   -
           /**
      -  118  
            * Filter that detects files named "METADATA".
      +  114   +
            */
      +  115  2
           private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter(
      +  116   +
                   "EGG-INFO");
      +  117   +
       
      +  118   +
           /**
       119   +
            * Filter that detects files named "METADATA".
      +  120  
            */
      -  120  1
           private static final NameFileFilter METADATA_FILTER = new NameFileFilter(
      -  121   -
                   METADATA);
      +  121  2
           private static final NameFileFilter METADATA_FILTER = new NameFileFilter(
       122   -
       
      +
                   METADATA);
       123   -
           /**
      +
       
       124   -
            * Filter that detects files named "PKG-INFO".
      +
           /**
       125   +
            * Filter that detects files named "PKG-INFO".
      +  126  
            */
      -  126  1
           private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter(
      -  127   -
                   PKG_INFO);
      +  127  2
           private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter(
       128   -
       
      +
                   PKG_INFO);
       129   -
           /**
      +
       
       130   -
            * The file filter used to determine which files this analyzer supports.
      +
           /**
       131   +
            * The file filter used to determine which files this analyzer supports.
      +  132  
            */
      -  132  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters(
      -  133  1
                   METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build();
      -  134   -
       
      +  133  4
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters(
      +  134  2
                   METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build();
       135   -
           /**
      +
       
       136   -
            * Returns the FileFilter
      +
           /**
       137   -
            *
      +
            * Returns the FileFilter
       138   -
            * @return the FileFilter
      +
            *
       139   -
            */
      +
            * @return the FileFilter
       140   -
           @Override
      +
            */
       141   +
           @Override
      +  142  
           protected FileFilter getFileFilter() {
      -  142  858
               return FILTER;
      -  143   -
           }
      +  143  1728
               return FILTER;
       144   -
       
      +
           }
       145   -
           /**
      +
       
       146   -
            * Returns the name of the analyzer.
      +
           /**
       147   -
            *
      +
            * Returns the name of the analyzer.
       148   -
            * @return the name of the analyzer.
      +
            *
       149   -
            */
      +
            * @return the name of the analyzer.
       150   -
           @Override
      +
            */
       151   +
           @Override
      +  152  
           public String getName() {
      -  152  5
               return ANALYZER_NAME;
      -  153   -
           }
      +  153  30
               return ANALYZER_NAME;
       154   -
       
      +
           }
       155   -
           /**
      +
       
       156   -
            * Returns the phase that the analyzer is intended to run in.
      +
           /**
       157   -
            *
      +
            * Returns the phase that the analyzer is intended to run in.
       158   -
            * @return the phase that the analyzer is intended to run in.
      +
            *
       159   -
            */
      +
            * @return the phase that the analyzer is intended to run in.
       160   -
           @Override
      +
            */
       161   +
           @Override
      +  162  
           public AnalysisPhase getAnalysisPhase() {
      -  162  3
               return ANALYSIS_PHASE;
      -  163   -
           }
      +  163  8
               return ANALYSIS_PHASE;
       164   -
       
      +
           }
       165   -
           /**
      +
       
       166   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +
           /**
       167   -
            *
      +
            * Returns the key used in the properties file to reference the analyzer's enabled property.
       168   -
            * @return the analyzer's enabled property setting key
      +
            *
       169   -
            */
      +
            * @return the analyzer's enabled property setting key
       170   -
           @Override
      +
            */
       171   +
           @Override
      +  172  
           protected String getAnalyzerEnabledSettingKey() {
      -  172  12
               return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
      -  173   -
           }
      +  173  28
               return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
       174   -
       
      +
           }
       175   -
           @Override
      +
       
       176   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +
           @Override
       177   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  178  
                   throws AnalysisException {
      -  178  6
               final File actualFile = dependency.getActualFile();
      -  179  6
               if (WHL_FILTER.accept(actualFile)) {
      -  180  1
                   collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER,
      -  181   +  179  12
               final File actualFile = dependency.getActualFile();
      +  180  12
               if (WHL_FILTER.accept(actualFile)) {
      +  181  2
                   collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER,
      +  182  
                           METADATA_FILTER);
      -  182  5
               } else if (EGG_OR_ZIP.accept(actualFile)) {
      -  183  2
                   collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER,
      -  184   -
                           PKG_INFO_FILTER);
      +  183  10
               } else if (EGG_OR_ZIP.accept(actualFile)) {
      +  184  4
                   collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER,
       185   +
                           PKG_INFO_FILTER);
      +  186  
               } else {
      -  186  3
                   final String name = actualFile.getName();
      -  187  3
                   final boolean metadata = METADATA.equals(name);
      -  188  3
                   if (metadata || PKG_INFO.equals(name)) {
      -  189  3
                       final File parent = actualFile.getParentFile();
      -  190  3
                       final String parentName = parent.getName();
      -  191  3
                       dependency.setDisplayFileName(parentName + "/" + name);
      -  192  3
                       if (parent.isDirectory()
      -  193  1
                               && (metadata && parentName.endsWith(".dist-info")
      -  194  2
                               || parentName.endsWith(".egg-info") || "EGG-INFO"
      -  195  1
                               .equals(parentName))) {
      -  196  3
                           collectWheelMetadata(dependency, actualFile);
      -  197   -
                       }
      +  187  6
                   final String name = actualFile.getName();
      +  188  6
                   final boolean metadata = METADATA.equals(name);
      +  189  6
                   if (metadata || PKG_INFO.equals(name)) {
      +  190  6
                       final File parent = actualFile.getParentFile();
      +  191  6
                       final String parentName = parent.getName();
      +  192  6
                       dependency.setDisplayFileName(parentName + "/" + name);
      +  193  6
                       if (parent.isDirectory()
      +  194  2
                               && (metadata && parentName.endsWith(".dist-info")
      +  195  4
                               || parentName.endsWith(".egg-info") || "EGG-INFO"
      +  196  2
                               .equals(parentName))) {
      +  197  6
                           collectWheelMetadata(dependency, actualFile);
       198   -
                   }
      +
                       }
       199   +
                   }
      +  200  
               }
      -  200  6
           }
      -  201   -
       
      +  201  12
           }
       202   -
           /**
      +
       
       203   -
            * Collects the meta data from an archive.
      +
           /**
       204   -
            *
      +
            * Collects the meta data from an archive.
       205   -
            * @param dependency the archive being scanned
      +
            *
       206   -
            * @param folderFilter the filter to apply to the folder
      +
            * @param dependency the archive being scanned
       207   -
            * @param metadataFilter the filter to apply to the meta data
      +
            * @param folderFilter the filter to apply to the folder
       208   -
            * @throws AnalysisException thrown when there is a problem analyzing the dependency
      +
            * @param metadataFilter the filter to apply to the meta data
       209   -
            */
      +
            * @throws AnalysisException thrown when there is a problem analyzing the dependency
       210   -
           private void collectMetadataFromArchiveFormat(Dependency dependency,
      +
            */
       211   -
                   FilenameFilter folderFilter, FilenameFilter metadataFilter)
      +
           private void collectMetadataFromArchiveFormat(Dependency dependency,
       212   +
                   FilenameFilter folderFilter, FilenameFilter metadataFilter)
      +  213  
                   throws AnalysisException {
      -  213  3
               final File temp = getNextTempDirectory();
      -  214  3
               LOGGER.debug("{} exists? {}", temp, temp.exists());
      -  215   +  214  6
               final File temp = getNextTempDirectory();
      +  215  6
               LOGGER.debug("{} exists? {}", temp, temp.exists());
      +  216  
               try {
      -  216  6
                   ExtractionUtil.extractFilesUsingFilter(
      -  217  3
                           new File(dependency.getActualFilePath()), temp,
      -  218   +  217  12
                   ExtractionUtil.extractFilesUsingFilter(
      +  218  6
                           new File(dependency.getActualFilePath()), temp,
      +  219  
                           metadataFilter);
      -  219  0
               } catch (ExtractionException ex) {
      -  220  0
                   throw new AnalysisException(ex);
      -  221  3
               }
      -  222   +  220  0
               } catch (ExtractionException ex) {
      +  221  0
                   throw new AnalysisException(ex);
      +  222  6
               }
      +  223  
       
      -  223  6
               collectWheelMetadata(
      -  224   +  224  12
               collectWheelMetadata(
      +  225  
                       dependency,
      -  225  3
                       getMatchingFile(getMatchingFile(temp, folderFilter),
      -  226   +  226  6
                       getMatchingFile(getMatchingFile(temp, folderFilter),
      +  227  
                               metadataFilter));
      -  227  3
           }
      -  228   -
       
      +  228  6
           }
       229   -
           /**
      +
       
       230   -
            * Makes sure a usable temporary directory is available.
      +
           /**
       231   -
            *
      +
            * Makes sure a usable temporary directory is available.
       232   -
            * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created
      +
            *
       233   -
            */
      +
            * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created
       234   -
           @Override
      +
            */
       235   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      -  236  8
               final File baseDir = Settings.getTempDirectory();
      -  237  8
               tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      -  238  8
               if (!tempFileLocation.delete()) {
      -  239  0
                   final String msg = String.format(
      -  240   -
                           "Unable to delete temporary file '%s'.",
      -  241  0
                           tempFileLocation.getAbsolutePath());
      -  242  0
                   throw new AnalysisException(msg);
      -  243   -
               }
      -  244  8
               if (!tempFileLocation.mkdirs()) {
      -  245  0
                   final String msg = String.format(
      -  246   -
                           "Unable to create directory '%s'.",
      -  247  0
                           tempFileLocation.getAbsolutePath());
      -  248  0
                   throw new AnalysisException(msg);
      -  249   -
               }
      -  250  8
           }
      -  251   -
       
      -  252   -
           /**
      -  253   -
            * Deletes any files extracted from the Wheel during analysis.
      -  254   -
            */
      -  255  
           @Override
      +  236   +
           protected void initializeFileTypeAnalyzer() throws Exception {
      +  237  16
               final File baseDir = Settings.getTempDirectory();
      +  238  16
               tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      +  239  16
               if (!tempFileLocation.delete()) {
      +  240  0
                   final String msg = String.format(
      +  241   +
                           "Unable to delete temporary file '%s'.",
      +  242  0
                           tempFileLocation.getAbsolutePath());
      +  243  0
                   throw new AnalysisException(msg);
      +  244   +
               }
      +  245  16
               if (!tempFileLocation.mkdirs()) {
      +  246  0
                   final String msg = String.format(
      +  247   +
                           "Unable to create directory '%s'.",
      +  248  0
                           tempFileLocation.getAbsolutePath());
      +  249  0
                   throw new AnalysisException(msg);
      +  250   +
               }
      +  251  16
           }
      +  252   +
       
      +  253   +
           /**
      +  254   +
            * Deletes any files extracted from the Wheel during analysis.
      +  255   +
            */
       256   +
           @Override
      +  257  
           public void close() {
      -  257  9
               if (tempFileLocation != null && tempFileLocation.exists()) {
      -  258  8
                   LOGGER.debug("Attempting to delete temporary files");
      -  259  8
                   final boolean success = FileUtils.delete(tempFileLocation);
      -  260  8
                   if (!success) {
      -  261  1
                       LOGGER.warn(
      -  262   -
                               "Failed to delete some temporary files, see the log for more details");
      +  258  20
               if (tempFileLocation != null && tempFileLocation.exists()) {
      +  259  16
                   LOGGER.debug("Attempting to delete temporary files");
      +  260  16
                   final boolean success = FileUtils.delete(tempFileLocation);
      +  261  16
                   if (!success) {
      +  262  2
                       LOGGER.warn(
       263   -
                   }
      +
                               "Failed to delete some temporary files, see the log for more details");
       264   -
               }
      -  265  9
           }
      -  266   -
       
      -  267   -
           /**
      -  268   -
            * Gathers evidence from the METADATA file.
      -  269   -
            *
      -  270   -
            * @param dependency the dependency being analyzed
      -  271   -
            * @param file a reference to the manifest/properties file
      -  272   -
            */
      -  273   -
           private static void collectWheelMetadata(Dependency dependency, File file) {
      -  274  6
               final InternetHeaders headers = getManifestProperties(file);
      -  275  6
               addPropertyToEvidence(headers, dependency.getVersionEvidence(),
      -  276   -
                       "Version", Confidence.HIGHEST);
      -  277  6
               addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name",
      -  278   -
                       Confidence.HIGHEST);
      -  279  6
               final String url = headers.getHeader("Home-page", null);
      -  280  6
               final EvidenceCollection vendorEvidence = dependency
      -  281  6
                       .getVendorEvidence();
      -  282  6
               if (StringUtils.isNotBlank(url)) {
      -  283  6
                   if (UrlStringUtils.isUrl(url)) {
      -  284  6
                       vendorEvidence.addEvidence(METADATA, "vendor", url,
      -  285   -
                               Confidence.MEDIUM);
      -  286  
                   }
      +  265   +
               }
      +  266  20
           }
      +  267   +
       
      +  268   +
           /**
      +  269   +
            * Gathers evidence from the METADATA file.
      +  270   +
            *
      +  271   +
            * @param dependency the dependency being analyzed
      +  272   +
            * @param file a reference to the manifest/properties file
      +  273   +
            */
      +  274   +
           private static void collectWheelMetadata(Dependency dependency, File file) {
      +  275  12
               final InternetHeaders headers = getManifestProperties(file);
      +  276  12
               addPropertyToEvidence(headers, dependency.getVersionEvidence(),
      +  277   +
                       "Version", Confidence.HIGHEST);
      +  278  12
               addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name",
      +  279   +
                       Confidence.HIGHEST);
      +  280  12
               final String url = headers.getHeader("Home-page", null);
      +  281  12
               final EvidenceCollection vendorEvidence = dependency
      +  282  12
                       .getVendorEvidence();
      +  283  12
               if (StringUtils.isNotBlank(url)) {
      +  284  12
                   if (UrlStringUtils.isUrl(url)) {
      +  285  12
                       vendorEvidence.addEvidence(METADATA, "vendor", url,
      +  286   +
                               Confidence.MEDIUM);
       287   +
                   }
      +  288  
               }
      -  288  6
               addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW);
      -  289  6
               final String summary = headers.getHeader("Summary", null);
      -  290  6
               if (StringUtils.isNotBlank(summary)) {
      -  291  6
                   JarAnalyzer
      -  292  6
                           .addDescription(dependency, summary, METADATA, "summary");
      -  293   +  289  12
               addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW);
      +  290  12
               final String summary = headers.getHeader("Summary", null);
      +  291  12
               if (StringUtils.isNotBlank(summary)) {
      +  292  12
                   JarAnalyzer
      +  293  12
                           .addDescription(dependency, summary, METADATA, "summary");
      +  294  
               }
      -  294  6
           }
      -  295   -
       
      +  295  12
           }
       296   -
           /**
      +
       
       297   -
            * Adds a value to the evidence collection.
      +
           /**
       298   -
            *
      +
            * Adds a value to the evidence collection.
       299   -
            * @param headers the properties collection
      +
            *
       300   -
            * @param evidence the evidence collection to add the value
      +
            * @param headers the properties collection
       301   -
            * @param property the property name
      +
            * @param evidence the evidence collection to add the value
       302   -
            * @param confidence the confidence of the evidence
      +
            * @param property the property name
       303   -
            */
      +
            * @param confidence the confidence of the evidence
       304   -
           private static void addPropertyToEvidence(InternetHeaders headers,
      +
            */
       305   +
           private static void addPropertyToEvidence(InternetHeaders headers,
      +  306  
                   EvidenceCollection evidence, String property, Confidence confidence) {
      -  306  18
               final String value = headers.getHeader(property, null);
      -  307  18
               LOGGER.debug("Property: {}, Value: {}", property, value);
      -  308  18
               if (StringUtils.isNotBlank(value)) {
      -  309  18
                   evidence.addEvidence(METADATA, property, value, confidence);
      -  310   +  307  36
               final String value = headers.getHeader(property, null);
      +  308  36
               LOGGER.debug("Property: {}, Value: {}", property, value);
      +  309  36
               if (StringUtils.isNotBlank(value)) {
      +  310  36
                   evidence.addEvidence(METADATA, property, value, confidence);
      +  311  
               }
      -  311  18
           }
      -  312   -
       
      +  312  36
           }
       313   -
           /**
      +
       
       314   -
            * Returns a list of files that match the given filter, this does not recursively scan the directory.
      +
           /**
       315   -
            *
      +
            * Returns a list of files that match the given filter, this does not recursively scan the directory.
       316   -
            * @param folder the folder to filter
      +
            *
       317   -
            * @param filter the filter to apply to the files in the directory
      +
            * @param folder the folder to filter
       318   -
            * @return the list of Files in the directory that match the provided filter
      +
            * @param filter the filter to apply to the files in the directory
       319   -
            */
      +
            * @return the list of Files in the directory that match the provided filter
       320   +
            */
      +  321  
           private static File getMatchingFile(File folder, FilenameFilter filter) {
      -  321  6
               File result = null;
      -  322  6
               final File[] matches = folder.listFiles(filter);
      -  323  6
               if (null != matches && 1 == matches.length) {
      -  324  6
                   result = matches[0];
      -  325   +  322  12
               File result = null;
      +  323  12
               final File[] matches = folder.listFiles(filter);
      +  324  12
               if (null != matches && 1 == matches.length) {
      +  325  12
                   result = matches[0];
      +  326  
               }
      -  326  6
               return result;
      -  327   -
           }
      +  327  12
               return result;
       328   -
       
      +
           }
       329   -
           /**
      +
       
       330   -
            * Reads the manifest entries from the provided file.
      -  331   -
            *
      -  332   -
            * @param manifest the manifest
      -  333   -
            * @return the manifest entries
      -  334   -
            */
      -  335   -
           private static InternetHeaders getManifestProperties(File manifest) {
      -  336  6
               final InternetHeaders result = new InternetHeaders();
      -  337  6
               if (null == manifest) {
      -  338  0
                   LOGGER.debug("Manifest file not found.");
      -  339   -
               } else {
      -  340   -
                   try {
      -  341  6
                       result.load(new AutoCloseInputStream(new BufferedInputStream(
      -  342   -
                               new FileInputStream(manifest))));
      -  343  0
                   } catch (MessagingException e) {
      -  344  0
                       LOGGER.warn(e.getMessage(), e);
      -  345  0
                   } catch (FileNotFoundException e) {
      -  346  0
                       LOGGER.warn(e.getMessage(), e);
      -  347  6
                   }
      -  348   -
               }
      -  349  6
               return result;
      -  350   -
           }
      -  351   -
       
      -  352  
           /**
      -  353   -
            * Retrieves the next temporary destination directory for extracting an archive.
      -  354   +  331   +
            * Reads the manifest entries from the provided file.
      +  332  
            *
      -  355   -
            * @return a directory
      -  356   -
            * @throws AnalysisException thrown if unable to create temporary directory
      -  357   +  333   +
            * @param manifest the manifest
      +  334   +
            * @return the manifest entries
      +  335  
            */
      -  358   -
           private File getNextTempDirectory() throws AnalysisException {
      -  359   -
               File directory;
      -  360   -
       
      -  361   -
               // getting an exception for some directories not being able to be
      -  362   -
               // created; might be because the directory already exists?
      -  363   -
               do {
      -  364  3
                   dirCount += 1;
      -  365  3
                   directory = new File(tempFileLocation, String.valueOf(dirCount));
      -  366  3
               } while (directory.exists());
      -  367  3
               if (!directory.mkdirs()) {
      -  368  0
                   throw new AnalysisException(String.format(
      -  369   -
                           "Unable to create temp directory '%s'.",
      -  370  0
                           directory.getAbsolutePath()));
      -  371   +  336   +
           private static InternetHeaders getManifestProperties(File manifest) {
      +  337  12
               final InternetHeaders result = new InternetHeaders();
      +  338  12
               if (null == manifest) {
      +  339  0
                   LOGGER.debug("Manifest file not found.");
      +  340   +
               } else {
      +  341   +
                   try {
      +  342  12
                       result.load(new AutoCloseInputStream(new BufferedInputStream(
      +  343   +
                               new FileInputStream(manifest))));
      +  344  0
                   } catch (MessagingException e) {
      +  345  0
                       LOGGER.warn(e.getMessage(), e);
      +  346  0
                   } catch (FileNotFoundException e) {
      +  347  0
                       LOGGER.warn(e.getMessage(), e);
      +  348  12
                   }
      +  349  
               }
      -  372  3
               return directory;
      -  373   +  350  12
               return result;
      +  351  
           }
      +  352   +
       
      +  353   +
           /**
      +  354   +
            * Retrieves the next temporary destination directory for extracting an archive.
      +  355   +
            *
      +  356   +
            * @return a directory
      +  357   +
            * @throws AnalysisException thrown if unable to create temporary directory
      +  358   +
            */
      +  359   +
           private File getNextTempDirectory() throws AnalysisException {
      +  360   +
               File directory;
      +  361   +
       
      +  362   +
               // getting an exception for some directories not being able to be
      +  363   +
               // created; might be because the directory already exists?
      +  364   +
               do {
      +  365  6
                   dirCount += 1;
      +  366  6
                   directory = new File(tempFileLocation, String.valueOf(dirCount));
      +  367  6
               } while (directory.exists());
      +  368  6
               if (!directory.mkdirs()) {
      +  369  0
                   throw new AnalysisException(String.format(
      +  370   +
                           "Unable to create temp directory '%s'.",
      +  371  0
                           directory.getAbsolutePath()));
      +  372   +
               }
      +  373  6
               return directory;
       374   +
           }
      +  375  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer.html index f1ee5fd37..5bff71a78 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      PythonPackageAnalyzer
      91%
      67/73
      75%
      15/20
      2.091
      PythonPackageAnalyzer
      91%
      66/72
      77%
      14/18
      2
       
      @@ -86,498 +86,513 @@  34  
       import java.io.IOException;
       35   -
       import java.util.ArrayList;
      +
       import java.nio.charset.Charset;
       36   -
       import java.util.List;
      +
       import java.util.ArrayList;
       37   -
       import java.util.regex.Matcher;
      +
       import java.util.List;
       38   -
       import java.util.regex.Pattern;
      +
       import java.util.regex.Matcher;
       39   -
       
      +
       import java.util.regex.Pattern;
       40   -
       /**
      +
       
       41   -
        * Used to analyze a Python package, and collect information that can be used to determine the associated CPE.
      +
       /**
       42   -
        *
      +
        * Used to analyze a Python package, and collect information that can be used to
       43   -
        * @author Dale Visser
      +
        * determine the associated CPE.
       44   -
        */
      -  45  7
       public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
      +
        *
      +  45   +
        * @author Dale Visser
       46   -
       
      +
        */
       47   -
           /**
      -  48   -
            * Used when compiling file scanning regex patterns.
      +
       @Experimental
      +  48  18
       public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
       49   -
            */
      +
       
       50   -
           private static final int REGEX_OPTIONS = Pattern.DOTALL
      +
           /**
       51   -
                   | Pattern.CASE_INSENSITIVE;
      +
            * Used when compiling file scanning regex patterns.
       52   -
       
      +
            */
       53   -
           /**
      +
           private static final int REGEX_OPTIONS = Pattern.DOTALL
       54   -
            * Filename extensions for files to be analyzed.
      +
                   | Pattern.CASE_INSENSITIVE;
       55   -
            */
      +
       
       56   -
           private static final String EXTENSIONS = "py";
      +
           /**
       57   -
       
      +
            * Filename extensions for files to be analyzed.
       58   -
           /**
      +
            */
       59   -
            * Pattern for matching the module docstring in a source file.
      +
           private static final String EXTENSIONS = "py";
       60   -
            */
      -  61  1
           private static final Pattern MODULE_DOCSTRING = Pattern.compile(
      +
       
      +  61   +
           /**
       62   -
                   "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS);
      +
            * Pattern for matching the module docstring in a source file.
       63   -
       
      -  64   -
           /**
      +
            */
      +  64  2
           private static final Pattern MODULE_DOCSTRING = Pattern.compile(
       65   -
            * Matches assignments to version variables in Python source code.
      +
                   "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS);
       66   -
            */
      -  67  1
           private static final Pattern VERSION_PATTERN = Pattern.compile(
      +
       
      +  67   +
           /**
       68   -
                   "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3",
      +
            * Matches assignments to version variables in Python source code.
       69   -
                   REGEX_OPTIONS);
      -  70   -
       
      +
            */
      +  70  2
           private static final Pattern VERSION_PATTERN = Pattern.compile(
       71   -
           /**
      +
                   "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3",
       72   -
            * Matches assignments to title variables in Python source code.
      +
                   REGEX_OPTIONS);
       73   -
            */
      -  74  1
           private static final Pattern TITLE_PATTERN = compileAssignPattern("title");
      +
       
      +  74   +
           /**
       75   -
       
      +
            * Matches assignments to title variables in Python source code.
       76   -
           /**
      -  77   -
            * Matches assignments to summary variables in Python source code.
      +
            */
      +  77  2
           private static final Pattern TITLE_PATTERN = compileAssignPattern("title");
       78   -
            */
      -  79  1
           private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary");
      +
       
      +  79   +
           /**
       80   -
       
      +
            * Matches assignments to summary variables in Python source code.
       81   -
           /**
      -  82   -
            * Matches assignments to URL/URL variables in Python source code.
      +
            */
      +  82  2
           private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary");
       83   -
            */
      -  84  1
           private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]");
      +
       
      +  84   +
           /**
       85   -
       
      +
            * Matches assignments to URL/URL variables in Python source code.
       86   -
           /**
      -  87   -
            * Matches assignments to home page variables in Python source code.
      +
            */
      +  87  2
           private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]");
       88   -
            */
      -  89  1
           private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page");
      +
       
      +  89   +
           /**
       90   -
       
      +
            * Matches assignments to home page variables in Python source code.
       91   -
           /**
      -  92   -
            * Matches assignments to author variables in Python source code.
      +
            */
      +  92  2
           private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page");
       93   -
            */
      -  94  1
           private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author");
      +
       
      +  94   +
           /**
       95   -
       
      +
            * Matches assignments to author variables in Python source code.
       96   -
           /**
      -  97   -
            * Filter that detects files named "__init__.py".
      +
            */
      +  97  2
           private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author");
       98   -
            */
      -  99  1
           private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py");
      +
       
      +  99   +
           /**
       100   -
       
      +
            * Filter that detects files named "__init__.py".
       101   -
           /**
      -  102   -
            * The file filter for python files.
      +
            */
      +  102  2
           private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py");
       103   -
            */
      -  104  1
           private static final FileFilter PY_FILTER = new SuffixFileFilter(".py");
      +
       
      +  104   +
           /**
       105   -
       
      +
            * The file filter for python files.
       106   -
           /**
      -  107   -
            * Returns the name of the Python Package Analyzer.
      +
            */
      +  107  2
           private static final FileFilter PY_FILTER = new SuffixFileFilter(".py");
       108   -
            *
      +
       
       109   -
            * @return the name of the analyzer
      +
           /**
       110   -
            */
      +
            * Returns the name of the Python Package Analyzer.
       111   -
           @Override
      +
            *
       112   -
           public String getName() {
      -  113  5
               return "Python Package Analyzer";
      +
            * @return the name of the analyzer
      +  113   +
            */
       114   -
           }
      +
           @Override
       115   -
       
      -  116   -
           /**
      +
           public String getName() {
      +  116  30
               return "Python Package Analyzer";
       117   -
            * Tell that we are used for information collection.
      +
           }
       118   -
            *
      +
       
       119   -
            * @return INFORMATION_COLLECTION
      +
           /**
       120   -
            */
      +
            * Tell that we are used for information collection.
       121   -
           @Override
      +
            *
       122   -
           public AnalysisPhase getAnalysisPhase() {
      -  123  3
               return AnalysisPhase.INFORMATION_COLLECTION;
      +
            * @return INFORMATION_COLLECTION
      +  123   +
            */
       124   -
           }
      +
           @Override
       125   -
       
      -  126   -
           /**
      +
           public AnalysisPhase getAnalysisPhase() {
      +  126  8
               return AnalysisPhase.INFORMATION_COLLECTION;
       127   -
            * The file filter used to determine which files this analyzer supports.
      -  128   -
            */
      -  129  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      -  130   -
       
      -  131   -
           /**
      -  132   -
            * Returns the FileFilter
      -  133   -
            *
      -  134   -
            * @return the FileFilter
      -  135   -
            */
      -  136   -
           @Override
      -  137   -
           protected FileFilter getFileFilter() {
      -  138  854
               return FILTER;
      -  139  
           }
      -  140   +  128  
       
      -  141   +  129  
           /**
      -  142   -
            * No-op initializer implementation.
      -  143   -
            *
      -  144   -
            * @throws Exception never thrown
      -  145   +  130   +
            * The file filter used to determine which files this analyzer supports.
      +  131  
            */
      -  146   +  132  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      +  133   +
       
      +  134   +
           /**
      +  135   +
            * Returns the FileFilter
      +  136   +
            *
      +  137   +
            * @return the FileFilter
      +  138   +
            */
      +  139  
           @Override
      -  147   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      -  148   -
               // Nothing to do here.
      -  149  3
           }
      -  150   +  140   +
           protected FileFilter getFileFilter() {
      +  141  1720
               return FILTER;
      +  142   +
           }
      +  143  
       
      -  151   +  144  
           /**
      -  152   -
            * Utility function to create a regex pattern matcher.
      -  153   +  145   +
            * No-op initializer implementation.
      +  146  
            *
      -  154   -
            * @param name the value to use when constructing the assignment pattern
      -  155   -
            * @return the compiled Pattern
      -  156   +  147   +
            * @throws Exception never thrown
      +  148  
            */
      +  149   +
           @Override
      +  150   +
           protected void initializeFileTypeAnalyzer() throws Exception {
      +  151   +
               // Nothing to do here.
      +  152  6
           }
      +  153   +
       
      +  154   +
           /**
      +  155   +
            * Utility function to create a regex pattern matcher.
      +  156   +
            *
       157   -
           private static Pattern compileAssignPattern(String name) {
      -  158  10
               return Pattern.compile(
      -  159  5
                       String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name),
      +
            * @param name the value to use when constructing the assignment pattern
      +  158   +
            * @return the compiled Pattern
      +  159   +
            */
       160   -
                       REGEX_OPTIONS);
      -  161   -
           }
      -  162   -
       
      +
           private static Pattern compileAssignPattern(String name) {
      +  161  20
               return Pattern.compile(
      +  162  10
                       String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name),
       163   -
           /**
      +
                       REGEX_OPTIONS);
       164   -
            * Analyzes python packages and adds evidence to the dependency.
      +
           }
       165   -
            *
      +
       
       166   -
            * @param dependency the dependency being analyzed
      +
           /**
       167   -
            * @param engine the engine being used to perform the scan
      +
            * Analyzes python packages and adds evidence to the dependency.
       168   -
            * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
      +
            *
       169   -
            */
      +
            * @param dependency the dependency being analyzed
       170   -
           @Override
      +
            * @param engine the engine being used to perform the scan
       171   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  172   -
                   throws AnalysisException {
      -  173  1
               final File file = dependency.getActualFile();
      -  174  1
               final File parent = file.getParentFile();
      -  175  1
               final String parentName = parent.getName();
      -  176  1
               boolean found = false;
      -  177  1
               if (INIT_PY_FILTER.accept(file)) {
      -  178  1
                   final File[] fileList = parent.listFiles(PY_FILTER);
      -  179  1
                   if (fileList != null) {
      -  180  4
                       for (final File sourceFile : fileList) {
      -  181  3
                           found |= analyzeFileContents(dependency, sourceFile);
      -  182   -
                       }
      -  183   -
                   }
      -  184   -
               }
      -  185  1
               if (found) {
      -  186  1
                   dependency.setDisplayFileName(parentName + "/__init__.py");
      -  187  1
                   dependency.getProductEvidence().addEvidence(file.getName(),
      -  188   -
                           "PackageName", parentName, Confidence.HIGH);
      -  189   -
               } else {
      -  190   -
                   // copy, alter and set in case some other thread is iterating over
      -  191  0
                   final List<Dependency> dependencies = new ArrayList<Dependency>(
      -  192  0
                           engine.getDependencies());
      -  193  0
                   dependencies.remove(dependency);
      -  194  0
                   engine.setDependencies(dependencies);
      -  195   -
               }
      -  196  1
           }
      -  197   -
       
      -  198   -
           /**
      -  199   -
            * This should gather information from leading docstrings, file comments, and assignments to __version__, __title__,
      -  200   -
            * __summary__, __uri__, __url__, __home*page__, __author__, and their all caps equivalents.
      -  201   -
            *
      -  202   -
            * @param dependency the dependency being analyzed
      -  203   -
            * @param file the file name to analyze
      -  204   -
            * @return whether evidence was found
      -  205  
            * @throws AnalysisException thrown if there is an unrecoverable error
      -  206   +  172   +
            * analyzing the dependency
      +  173  
            */
      -  207   -
           private boolean analyzeFileContents(Dependency dependency, File file)
      -  208   -
                   throws AnalysisException {
      -  209   -
               String contents;
      -  210   -
               try {
      -  211  3
                   contents = FileUtils.readFileToString(file).trim();
      -  212  0
               } catch (IOException e) {
      -  213  0
                   throw new AnalysisException(
      -  214   -
                           "Problem occurred while reading dependency file.", e);
      -  215  3
               }
      -  216  3
               boolean found = false;
      -  217  3
               if (!contents.isEmpty()) {
      -  218  3
                   final String source = file.getName();
      -  219  6
                   found = gatherEvidence(VERSION_PATTERN, contents, source,
      -  220  3
                           dependency.getVersionEvidence(), "SourceVersion",
      -  221   -
                           Confidence.MEDIUM);
      -  222  3
                   found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents,
      -  223   -
                           source, "summary");
      -  224  3
                   if (INIT_PY_FILTER.accept(file)) {
      -  225  1
                       found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2,
      -  226   -
                               contents, source, "docstring");
      -  227   -
                   }
      -  228  6
                   found |= gatherEvidence(TITLE_PATTERN, contents, source,
      -  229  3
                           dependency.getProductEvidence(), "SourceTitle",
      -  230   -
                           Confidence.LOW);
      -  231  3
                   final EvidenceCollection vendorEvidence = dependency
      -  232  3
                           .getVendorEvidence();
      -  233  3
                   found |= gatherEvidence(AUTHOR_PATTERN, contents, source,
      -  234   -
                           vendorEvidence, "SourceAuthor", Confidence.MEDIUM);
      -  235  3
                   found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
      -  236   -
                           source, "URL", contents);
      -  237  3
                   found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
      -  238   -
                           vendorEvidence, source, "HomePage", contents);
      -  239   -
               }
      -  240  3
               return found;
      -  241   -
           }
      -  242   -
       
      -  243   -
           /**
      -  244   -
            * Adds summary information to the dependency
      -  245   -
            *
      -  246   -
            * @param dependency the dependency being analyzed
      -  247   -
            * @param pattern the pattern used to perform analysis
      -  248   -
            * @param group the group from the pattern that indicates the data to use
      -  249   -
            * @param contents the data being analyzed
      -  250   -
            * @param source the source name to use when recording the evidence
      -  251   -
            * @param key the key name to use when recording the evidence
      -  252   -
            * @return true if evidence was collected; otherwise false
      -  253   -
            */
      -  254   -
           private boolean addSummaryInfo(Dependency dependency, Pattern pattern,
      -  255   -
                   int group, String contents, String source, String key) {
      -  256  4
               final Matcher matcher = pattern.matcher(contents);
      -  257  4
               final boolean found = matcher.find();
      -  258  4
               if (found) {
      -  259  1
                   JarAnalyzer.addDescription(dependency, matcher.group(group),
      -  260   -
                           source, key);
      -  261   -
               }
      -  262  4
               return found;
      -  263   -
           }
      -  264   -
       
      -  265   -
           /**
      -  266   -
            * Collects evidence from the home page URL.
      -  267   -
            *
      -  268   -
            * @param pattern the pattern to match
      -  269   -
            * @param evidence the evidence collection to add the evidence to
      -  270   -
            * @param source the source of the evidence
      -  271   -
            * @param name the name of the evidence
      -  272   -
            * @param contents the home page URL
      -  273   -
            * @return true if evidence was collected; otherwise false
      -  274   -
            */
      -  275   -
           private boolean gatherHomePageEvidence(Pattern pattern,
      -  276   -
                   EvidenceCollection evidence, String source, String name,
      -  277   -
                   String contents) {
      -  278  6
               final Matcher matcher = pattern.matcher(contents);
      -  279  6
               boolean found = false;
      -  280  6
               if (matcher.find()) {
      -  281  1
                   final String url = matcher.group(4);
      -  282  1
                   if (UrlStringUtils.isUrl(url)) {
      -  283  1
                       found = true;
      -  284  1
                       evidence.addEvidence(source, name, url, Confidence.MEDIUM);
      -  285   -
                   }
      -  286   -
               }
      -  287  6
               return found;
      -  288   -
           }
      -  289   -
       
      -  290   -
           /**
      -  291   -
            * Gather evidence from a Python source file using the given string assignment regex pattern.
      -  292   -
            *
      -  293   -
            * @param pattern to scan contents with
      -  294   -
            * @param contents of Python source file
      -  295   -
            * @param source for storing evidence
      -  296   -
            * @param evidence to store evidence in
      -  297   -
            * @param name of evidence
      -  298   -
            * @param confidence in evidence
      -  299   -
            * @return whether evidence was found
      -  300   -
            */
      -  301   -
           private boolean gatherEvidence(Pattern pattern, String contents,
      -  302   -
                   String source, EvidenceCollection evidence, String name,
      -  303   -
                   Confidence confidence) {
      -  304  9
               final Matcher matcher = pattern.matcher(contents);
      -  305  9
               final boolean found = matcher.find();
      -  306  9
               if (found) {
      -  307  3
                   evidence.addEvidence(source, name, matcher.group(4), confidence);
      -  308   -
               }
      -  309  9
               return found;
      -  310   -
           }
      -  311   -
       
      -  312   +  174  
           @Override
      -  313   -
           protected String getAnalyzerEnabledSettingKey() {
      -  314  7
               return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED;
      -  315   +  175   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  176   +
                   throws AnalysisException {
      +  177  2
               final File file = dependency.getActualFile();
      +  178  2
               final File parent = file.getParentFile();
      +  179  2
               final String parentName = parent.getName();
      +  180  2
               if (INIT_PY_FILTER.accept(file)) {
      +  181   +
                   //by definition, the containing folder of __init__.py is considered the package, even the file is empty:
      +  182   +
                   //"The __init__.py files are required to make Python treat the directories as containing packages"
      +  183   +
                   //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html;
      +  184  2
                   dependency.setDisplayFileName(parentName + "/__init__.py");
      +  185  2
                   dependency.getProductEvidence().addEvidence(file.getName(),
      +  186   +
                           "PackageName", parentName, Confidence.HIGHEST);
      +  187   +
       
      +  188  2
                   final File[] fileList = parent.listFiles(PY_FILTER);
      +  189  2
                   if (fileList != null) {
      +  190  8
                       for (final File sourceFile : fileList) {
      +  191  6
                           analyzeFileContents(dependency, sourceFile);
      +  192   +
                       }
      +  193   +
                   }
      +  194  2
               } else {
      +  195   +
                   // copy, alter and set in case some other thread is iterating over
      +  196  0
                   final List<Dependency> dependencies = new ArrayList<Dependency>(
      +  197  0
                           engine.getDependencies());
      +  198  0
                   dependencies.remove(dependency);
      +  199  0
                   engine.setDependencies(dependencies);
      +  200   +
               }
      +  201  2
           }
      +  202   +
       
      +  203   +
           /**
      +  204   +
            * This should gather information from leading docstrings, file comments,
      +  205   +
            * and assignments to __version__, __title__, __summary__, __uri__, __url__,
      +  206   +
            * __home*page__, __author__, and their all caps equivalents.
      +  207   +
            *
      +  208   +
            * @param dependency the dependency being analyzed
      +  209   +
            * @param file the file name to analyze
      +  210   +
            * @return whether evidence was found
      +  211   +
            * @throws AnalysisException thrown if there is an unrecoverable error
      +  212   +
            */
      +  213   +
           private boolean analyzeFileContents(Dependency dependency, File file)
      +  214   +
                   throws AnalysisException {
      +  215   +
               String contents;
      +  216   +
               try {
      +  217  6
                   contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim();
      +  218  0
               } catch (IOException e) {
      +  219  0
                   throw new AnalysisException(
      +  220   +
                           "Problem occurred while reading dependency file.", e);
      +  221  6
               }
      +  222  6
               boolean found = false;
      +  223  6
               if (!contents.isEmpty()) {
      +  224  6
                   final String source = file.getName();
      +  225  12
                   found = gatherEvidence(VERSION_PATTERN, contents, source,
      +  226  6
                           dependency.getVersionEvidence(), "SourceVersion",
      +  227   +
                           Confidence.MEDIUM);
      +  228  6
                   found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents,
      +  229   +
                           source, "summary");
      +  230  6
                   if (INIT_PY_FILTER.accept(file)) {
      +  231  2
                       found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2,
      +  232   +
                               contents, source, "docstring");
      +  233   +
                   }
      +  234  12
                   found |= gatherEvidence(TITLE_PATTERN, contents, source,
      +  235  6
                           dependency.getProductEvidence(), "SourceTitle",
      +  236   +
                           Confidence.LOW);
      +  237  6
                   final EvidenceCollection vendorEvidence = dependency
      +  238  6
                           .getVendorEvidence();
      +  239  6
                   found |= gatherEvidence(AUTHOR_PATTERN, contents, source,
      +  240   +
                           vendorEvidence, "SourceAuthor", Confidence.MEDIUM);
      +  241  6
                   found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
      +  242   +
                           source, "URL", contents);
      +  243  6
                   found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
      +  244   +
                           vendorEvidence, source, "HomePage", contents);
      +  245   +
               }
      +  246  6
               return found;
      +  247  
           }
      -  316   +  248   +
       
      +  249   +
           /**
      +  250   +
            * Adds summary information to the dependency
      +  251   +
            *
      +  252   +
            * @param dependency the dependency being analyzed
      +  253   +
            * @param pattern the pattern used to perform analysis
      +  254   +
            * @param group the group from the pattern that indicates the data to use
      +  255   +
            * @param contents the data being analyzed
      +  256   +
            * @param source the source name to use when recording the evidence
      +  257   +
            * @param key the key name to use when recording the evidence
      +  258   +
            * @return true if evidence was collected; otherwise false
      +  259   +
            */
      +  260   +
           private boolean addSummaryInfo(Dependency dependency, Pattern pattern,
      +  261   +
                   int group, String contents, String source, String key) {
      +  262  8
               final Matcher matcher = pattern.matcher(contents);
      +  263  8
               final boolean found = matcher.find();
      +  264  8
               if (found) {
      +  265  2
                   JarAnalyzer.addDescription(dependency, matcher.group(group),
      +  266   +
                           source, key);
      +  267   +
               }
      +  268  8
               return found;
      +  269   +
           }
      +  270   +
       
      +  271   +
           /**
      +  272   +
            * Collects evidence from the home page URL.
      +  273   +
            *
      +  274   +
            * @param pattern the pattern to match
      +  275   +
            * @param evidence the evidence collection to add the evidence to
      +  276   +
            * @param source the source of the evidence
      +  277   +
            * @param name the name of the evidence
      +  278   +
            * @param contents the home page URL
      +  279   +
            * @return true if evidence was collected; otherwise false
      +  280   +
            */
      +  281   +
           private boolean gatherHomePageEvidence(Pattern pattern,
      +  282   +
                   EvidenceCollection evidence, String source, String name,
      +  283   +
                   String contents) {
      +  284  12
               final Matcher matcher = pattern.matcher(contents);
      +  285  12
               boolean found = false;
      +  286  12
               if (matcher.find()) {
      +  287  2
                   final String url = matcher.group(4);
      +  288  2
                   if (UrlStringUtils.isUrl(url)) {
      +  289  2
                       found = true;
      +  290  2
                       evidence.addEvidence(source, name, url, Confidence.MEDIUM);
      +  291   +
                   }
      +  292   +
               }
      +  293  12
               return found;
      +  294   +
           }
      +  295   +
       
      +  296   +
           /**
      +  297   +
            * Gather evidence from a Python source file using the given string
      +  298   +
            * assignment regex pattern.
      +  299   +
            *
      +  300   +
            * @param pattern to scan contents with
      +  301   +
            * @param contents of Python source file
      +  302   +
            * @param source for storing evidence
      +  303   +
            * @param evidence to store evidence in
      +  304   +
            * @param name of evidence
      +  305   +
            * @param confidence in evidence
      +  306   +
            * @return whether evidence was found
      +  307   +
            */
      +  308   +
           private boolean gatherEvidence(Pattern pattern, String contents,
      +  309   +
                   String source, EvidenceCollection evidence, String name,
      +  310   +
                   Confidence confidence) {
      +  311  18
               final Matcher matcher = pattern.matcher(contents);
      +  312  18
               final boolean found = matcher.find();
      +  313  18
               if (found) {
      +  314  6
                   evidence.addEvidence(source, name, matcher.group(4), confidence);
      +  315   +
               }
      +  316  18
               return found;
      +  317   +
           }
      +  318   +
       
      +  319   +
           @Override
      +  320   +
           protected String getAnalyzerEnabledSettingKey() {
      +  321  18
               return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED;
      +  322   +
           }
      +  323  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.html index 14484296d..c0c0af8b3 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      RubyBundleAuditAnalyzer
      16%
      28/169
      4%
      3/68
      4.615
      RubyBundleAuditAnalyzer
      16%
      32/200
      2%
      2/74
      5.154
       
      @@ -56,484 +56,711 @@  19  
       
       20   -
       import org.apache.commons.io.FileUtils;
      +
       import java.io.BufferedReader;
       21   -
       import org.owasp.dependencycheck.Engine;
      +
       import java.io.File;
       22   -
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      +
       import java.io.FileFilter;
       23   -
       import org.owasp.dependencycheck.dependency.Confidence;
      +
       import java.io.IOException;
       24   -
       import org.owasp.dependencycheck.dependency.Dependency;
      +
       import java.io.InputStreamReader;
       25   -
       import org.owasp.dependencycheck.dependency.Reference;
      +
       import java.util.ArrayList;
       26   -
       import org.owasp.dependencycheck.dependency.Vulnerability;
      +
       import java.util.HashMap;
       27   -
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      +
       import java.util.List;
       28   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import java.util.Map;
       29   -
       import org.slf4j.Logger;
      +
       import java.nio.charset.Charset;
       30   -
       import org.slf4j.LoggerFactory;
      +
       import org.apache.commons.io.FileUtils;
       31   -
       
      +
       import org.owasp.dependencycheck.Engine;
       32   -
       import java.io.*;
      +
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
       33   -
       import java.util.*;
      +
       import org.owasp.dependencycheck.data.nvdcve.CveDB;
       34   -
       
      +
       import org.owasp.dependencycheck.dependency.Confidence;
       35   -
       /**
      +
       import org.owasp.dependencycheck.dependency.Dependency;
       36   -
        * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party bundle-audit tool.
      +
       import org.owasp.dependencycheck.dependency.Reference;
       37   -
        *
      +
       import org.owasp.dependencycheck.dependency.Vulnerability;
       38   -
        * @author Dale Visser
      +
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
       39   -
        */
      -  40  8
       public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
      +
       import org.owasp.dependencycheck.utils.Settings;
      +  40   +
       import org.slf4j.Logger;
       41   -
       
      -  42  1
           private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class);
      +
       import org.slf4j.LoggerFactory;
      +  42   +
       import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
       43  
       
       44   -
           /**
      +
       /**
       45   -
            * The name of the analyzer.
      +
        * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party
       46   -
            */
      +
        * bundle-audit tool.
       47   -
           private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer";
      +
        *
       48   -
       
      +
        * @author Dale Visser
       49   -
           /**
      +
        */
       50   -
            * The phase that this analyzer is intended to run in.
      -  51   -
            */
      -  52  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION;
      -  53   +
       @Experimental
      +  51  24
       public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
      +  52  
       
      -  54  1
           private static final FileFilter FILTER
      -  55  1
                   = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build();
      +  53  2
           private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class);
      +  54   +
       
      +  55   +
           /**
       56   -
           public static final String NAME = "Name: ";
      +
            * The name of the analyzer.
       57   -
           public static final String VERSION = "Version: ";
      +
            */
       58   -
           public static final String ADVISORY = "Advisory: ";
      +
           private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer";
       59   -
           public static final String CRITICALITY = "Criticality: ";
      +
       
       60   -
       
      +
           /**
       61   -
           /**
      +
            * The phase that this analyzer is intended to run in.
       62   -
            * @return a filter that accepts files named Gemfile.lock
      -  63  
            */
      +  63  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION;
       64   -
           @Override
      +
           /**
       65   -
           protected FileFilter getFileFilter() {
      -  66  854
               return FILTER;
      -  67   -
           }
      +
            * The filter defining which files will be analyzed.
      +  66   +
            */
      +  67  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build();
       68   -
       
      +
           /**
       69   -
           /**
      +
            * Name.
       70   -
            * Launch bundle-audit.
      +
            */
       71   -
            *
      +
           public static final String NAME = "Name: ";
       72   -
            * @return a handle to the process
      +
           /**
       73   -
            */
      +
            * Version.
       74   -
           private Process launchBundleAudit(File folder) throws AnalysisException {
      -  75  2
               if (!folder.isDirectory()) {
      -  76  0
                   throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath()));
      +
            */
      +  75   +
           public static final String VERSION = "Version: ";
      +  76   +
           /**
       77   -
               }
      -  78  2
               final List<String> args = new ArrayList<String>();
      -  79  2
               final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH);
      -  80  2
               args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath);
      -  81  2
               args.add("check");
      -  82  2
               args.add("--verbose");
      -  83  2
               final ProcessBuilder builder = new ProcessBuilder(args);
      -  84  2
               builder.directory(folder);
      +
            * Advisory.
      +  78   +
            */
      +  79   +
           public static final String ADVISORY = "Advisory: ";
      +  80   +
           /**
      +  81   +
            * Criticality.
      +  82   +
            */
      +  83   +
           public static final String CRITICALITY = "Criticality: ";
      +  84   +
       
       85   -
               try {
      -  86  2
                       LOGGER.info("Launching: " + args + " from " + folder);
      -  87  2
                   return builder.start();
      -  88  2
               } catch (IOException ioe) {
      -  89  2
                   throw new AnalysisException("bundle-audit failure", ioe);
      +
           /**
      +  86   +
            * The DAL.
      +  87   +
            */
      +  88   +
           private CveDB cvedb;
      +  89   +
       
       90   -
               }
      +
           /**
       91   -
           }
      +
            * @return a filter that accepts files named Gemfile.lock
       92   -
       
      +
            */
       93   -
           /**
      +
           @Override
       94   -
            * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location.
      -  95   -
            *
      +
           protected FileFilter getFileFilter() {
      +  95  1720
               return FILTER;
       96   -
            * @throws Exception if anything goes wrong
      +
           }
       97   -
            */
      +
       
       98   -
           @Override
      +
           /**
       99   -
           public void initializeFileTypeAnalyzer() throws Exception {
      +
            * Launch bundle-audit.
       100   -
               // Now, need to see if bundle-audit actually runs from this location.
      -  101  2
                   Process process = null;
      +
            *
      +  101   +
            * @param folder directory that contains bundle audit
       102   -
                   try {
      -  103  2
                       process = launchBundleAudit(Settings.getTempDirectory());
      +
            * @return a handle to the process
      +  103   +
            * @throws AnalysisException thrown when there is an issue launching bundle
       104   -
                   }
      -  105  2
                   catch(AnalysisException ae) {
      -  106  2
                           LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME);
      -  107  2
                   setEnabled(false);
      -  108  2
                   throw ae;
      -  109  0
                   }
      -  110   -
                   
      -  111  0
               int exitValue = process.waitFor();
      -  112  0
               if (0 == exitValue) {
      -  113  0
                   LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue);
      -  114  0
                   setEnabled(false);
      -  115  0
                   throw new AnalysisException("Unexpected exit code from bundle-audit process.");
      -  116   -
               } else {
      -  117  0
                   BufferedReader reader = null;
      -  118   -
                   try {
      -  119  0
                       reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
      -  120  0
                       if (!reader.ready()) {
      -  121  0
                           LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME);
      -  122  0
                           setEnabled(false);
      -  123  0
                           throw new AnalysisException("Bundle-audit error stream unexpectedly not ready.");
      +
            * audit
      +  105   +
            */
      +  106   +
           private Process launchBundleAudit(File folder) throws AnalysisException {
      +  107  8
               if (!folder.isDirectory()) {
      +  108  0
                   throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath()));
      +  109   +
               }
      +  110  8
               final List<String> args = new ArrayList<String>();
      +  111  8
               final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH);
      +  112  8
               args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath);
      +  113  8
               args.add("check");
      +  114  8
               args.add("--verbose");
      +  115  8
               final ProcessBuilder builder = new ProcessBuilder(args);
      +  116  8
               builder.directory(folder);
      +  117   +
               try {
      +  118  8
                   LOGGER.info("Launching: " + args + " from " + folder);
      +  119  8
                   return builder.start();
      +  120  8
               } catch (IOException ioe) {
      +  121  8
                   throw new AnalysisException("bundle-audit failure", ioe);
      +  122   +
               }
      +  123   +
           }
       124   -
                       } else {
      -  125  0
                           final String line = reader.readLine();
      -  126  0
                           if (line == null || !line.contains("Errno::ENOENT")) {
      -  127  0
                               LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line);
      -  128  0
                               setEnabled(false);
      -  129  0
                               throw new AnalysisException("Unexpected bundle-audit output.");
      +
       
      +  125   +
           /**
      +  126   +
            * Initialize the analyzer. In this case, extract GrokAssembly.exe to a
      +  127   +
            * temporary location.
      +  128   +
            *
      +  129   +
            * @throws Exception if anything goes wrong
       130   -
                           }
      +
            */
       131   -
                       }
      +
           @Override
       132   -
                   } finally {
      -  133  0
                       if (null != reader) {
      -  134  0
                           reader.close();
      -  135   -
                       }
      -  136   -
                   }
      -  137   -
               }
      -  138   -
                   
      -  139  0
               if (isEnabled()) {
      -  140  0
                   LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" "
      -  141   -
                           + "occasionally to keep its database up to date.");
      +
           public void initializeFileTypeAnalyzer() throws Exception {
      +  133   +
               try {
      +  134  8
                   cvedb = new CveDB();
      +  135  8
                   cvedb.open();
      +  136  0
               } catch (DatabaseException ex) {
      +  137  0
                   LOGGER.warn("Exception opening the database");
      +  138  0
                   LOGGER.debug("error", ex);
      +  139  0
                   setEnabled(false);
      +  140  0
                   throw ex;
      +  141  8
               }
       142   -
               }
      -  143  0
           }
      +
               // Now, need to see if bundle-audit actually runs from this location.
      +  143  8
               Process process = null;
       144   -
       
      -  145   -
           /**
      -  146   -
            * Returns the name of the analyzer.
      -  147   -
            *
      -  148   -
            * @return the name of the analyzer.
      -  149   -
            */
      -  150   -
           @Override
      -  151   -
           public String getName() {
      -  152  5
               return ANALYZER_NAME;
      +
               try {
      +  145  8
                   process = launchBundleAudit(Settings.getTempDirectory());
      +  146  8
               } catch (AnalysisException ae) {
      +  147  8
                   LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME);
      +  148  8
                   setEnabled(false);
      +  149  8
                   cvedb.close();
      +  150  8
                   cvedb = null;
      +  151  8
                   throw ae;
      +  152  0
               }
       153   -
           }
      -  154  
       
      -  155   -
           /**
      -  156   -
            * Returns the phase that the analyzer is intended to run in.
      -  157   -
            *
      -  158   -
            * @return the phase that the analyzer is intended to run in.
      +  154  0
               final int exitValue = process.waitFor();
      +  155  0
               if (0 == exitValue) {
      +  156  0
                   LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue);
      +  157  0
                   setEnabled(false);
      +  158  0
                   throw new AnalysisException("Unexpected exit code from bundle-audit process.");
       159   -
            */
      -  160   -
           @Override
      +
               } else {
      +  160  0
                   BufferedReader reader = null;
       161   -
           public AnalysisPhase getAnalysisPhase() {
      -  162  3
               return ANALYSIS_PHASE;
      -  163   -
           }
      -  164   -
       
      -  165   -
           /**
      -  166   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +
                   try {
      +  162  0
                       reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
      +  163  0
                       if (!reader.ready()) {
      +  164  0
                           LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME);
      +  165  0
                           setEnabled(false);
      +  166  0
                           throw new AnalysisException("Bundle-audit error stream unexpectedly not ready.");
       167   -
            *
      -  168   -
            * @return the analyzer's enabled property setting key
      -  169   -
            */
      -  170   -
           @Override
      -  171   -
           protected String getAnalyzerEnabledSettingKey() {
      -  172  8
               return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED;
      +
                       } else {
      +  168  0
                           final String line = reader.readLine();
      +  169  0
                           if (line == null || !line.contains("Errno::ENOENT")) {
      +  170  0
                               LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line);
      +  171  0
                               setEnabled(false);
      +  172  0
                               throw new AnalysisException("Unexpected bundle-audit output.");
       173   -
           }
      +
                           }
       174   -
       
      +
                       }
       175   -
           /**
      -  176   -
            * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have successfully initialized, and it will be necessary
      -  177   -
            * to disable {@link RubyGemspecAnalyzer}.
      +
                   } finally {
      +  176  0
                       if (null != reader) {
      +  177  0
                           reader.close();
       178   -
            */
      -  179  8
           private boolean needToDisableGemspecAnalyzer = true;
      +
                       }
      +  179   +
                   }
       180   -
       
      +
               }
       181   -
           @Override
      -  182   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  183   -
                   throws AnalysisException {
      -  184  0
               if (needToDisableGemspecAnalyzer) {
      -  185  0
                   boolean failed = true;
      -  186  0
                   final String className = RubyGemspecAnalyzer.class.getName();
      -  187  0
                   for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) {
      -  188  0
                       if (analyzer instanceof RubyGemspecAnalyzer) {
      -  189  0
                           ((RubyGemspecAnalyzer) analyzer).setEnabled(false);
      -  190  0
                           LOGGER.info("Disabled " + className + " to avoid noisy duplicate results.");
      -  191  0
                           failed = false;
      +
       
      +  182  0
               if (isEnabled()) {
      +  183  0
                   LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" "
      +  184   +
                           + "occasionally to keep its database up to date.");
      +  185   +
               }
      +  186  0
           }
      +  187   +
       
      +  188   +
           /**
      +  189   +
            * Returns the name of the analyzer.
      +  190   +
            *
      +  191   +
            * @return the name of the analyzer.
       192   -
                       }
      -  193  0
                   }
      -  194  0
                   if (failed) {
      -  195  0
                       LOGGER.warn("Did not find" + className + '.');
      +
            */
      +  193   +
           @Override
      +  194   +
           public String getName() {
      +  195  32
               return ANALYZER_NAME;
       196   -
                   }
      -  197  0
                   needToDisableGemspecAnalyzer = false;
      +
           }
      +  197   +
       
       198   -
               }
      -  199  0
               final File parentFile = dependency.getActualFile().getParentFile();
      -  200  0
               final Process process = launchBundleAudit(parentFile);
      +
           /**
      +  199   +
            * Returns the phase that the analyzer is intended to run in.
      +  200   +
            *
       201   -
               try {
      -  202  0
                   process.waitFor();
      -  203  0
               } catch (InterruptedException ie) {
      -  204  0
                   throw new AnalysisException("bundle-audit process interrupted", ie);
      -  205  0
               }
      -  206  0
               BufferedReader rdr = null;
      +
            * @return the phase that the analyzer is intended to run in.
      +  202   +
            */
      +  203   +
           @Override
      +  204   +
           public AnalysisPhase getAnalysisPhase() {
      +  205  8
               return ANALYSIS_PHASE;
      +  206   +
           }
       207   -
               try {
      -  208  0
                       BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
      -  209  0
                       while(errReader.ready()) {
      -  210  0
                               String error = errReader.readLine();
      -  211  0
                               LOGGER.warn(error);
      -  212  0
                       }
      -  213  0
                   rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
      -  214  0
                   processBundlerAuditOutput(dependency, engine, rdr);
      -  215  0
               } catch (IOException ioe) {
      -  216  0
                   LOGGER.warn("bundle-audit failure", ioe);
      +
       
      +  208   +
           /**
      +  209   +
            * Returns the key used in the properties file to reference the analyzer's
      +  210   +
            * enabled property.
      +  211   +
            *
      +  212   +
            * @return the analyzer's enabled property setting key
      +  213   +
            */
      +  214   +
           @Override
      +  215   +
           protected String getAnalyzerEnabledSettingKey() {
      +  216  24
               return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED;
       217   -
               } finally {
      -  218  0
                   if (null != rdr) {
      +
           }
      +  218   +
       
       219   -
                       try {
      -  220  0
                           rdr.close();
      -  221  0
                       } catch (IOException ioe) {
      -  222  0
                           LOGGER.warn("bundle-audit close failure", ioe);
      -  223  0
                       }
      -  224   -
                   }
      +
           /**
      +  220   +
            * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have
      +  221   +
            * successfully initialized, and it will be necessary to disable
      +  222   +
            * {@link RubyGemspecAnalyzer}.
      +  223   +
            */
      +  224  24
           private boolean needToDisableGemspecAnalyzer = true;
       225   -
               }
      +
       
       226   -
       
      -  227  0
           }
      +
           /**
      +  227   +
            * Determines if the analyzer can analyze the given file type.
       228   -
       
      +
            *
       229   -
           private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException {
      -  230  0
               final String parentName = original.getActualFile().getParentFile().getName();
      -  231  0
               final String fileName = original.getFileName();
      -  232  0
               Dependency dependency = null;
      -  233  0
               Vulnerability vulnerability = null;
      -  234  0
               String gem = null;
      -  235  0
               final Map<String, Dependency> map = new HashMap<String, Dependency>();
      -  236  0
               boolean appendToDescription = false;
      -  237  0
               while (rdr.ready()) {
      -  238  0
                   final String nextLine = rdr.readLine();
      -  239  0
                   if (null == nextLine) {
      -  240  0
                       break;
      -  241  0
                   } else if (nextLine.startsWith(NAME)) {
      -  242  0
                       appendToDescription = false;
      -  243  0
                       gem = nextLine.substring(NAME.length());
      -  244  0
                       if (!map.containsKey(gem)) {
      -  245  0
                           map.put(gem, createDependencyForGem(engine, parentName, fileName, gem));
      -  246   +
            * @param dependency the dependency to determine if it can analyze
      +  230   +
            * @param engine the dependency-check engine
      +  231   +
            * @throws AnalysisException thrown if there is an analysis exception.
      +  232   +
            */
      +  233   +
           @Override
      +  234   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  235   +
                   throws AnalysisException {
      +  236  0
               if (needToDisableGemspecAnalyzer) {
      +  237  0
                   boolean failed = true;
      +  238  0
                   final String className = RubyGemspecAnalyzer.class.getName();
      +  239  0
                   for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) {
      +  240  0
                       if (analyzer instanceof RubyBundlerAnalyzer) {
      +  241  0
                           ((RubyBundlerAnalyzer) analyzer).setEnabled(false);
      +  242  0
                           LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results.");
      +  243  0
                       } else if (analyzer instanceof RubyGemspecAnalyzer) {
      +  244  0
                           ((RubyGemspecAnalyzer) analyzer).setEnabled(false);
      +  245  0
                           LOGGER.info("Disabled " + className + " to avoid noisy duplicate results.");
      +  246  0
                           failed = false;
      +  247  
                       }
      -  247  0
                       dependency = map.get(gem);
      -  248  0
                       LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  249  0
                   } else if (nextLine.startsWith(VERSION)) {
      -  250  0
                       vulnerability = createVulnerability(parentName, dependency, vulnerability, gem, nextLine);
      -  251  0
                   } else if (nextLine.startsWith(ADVISORY)) {
      -  252  0
                       setVulnerabilityName(parentName, dependency, vulnerability, nextLine);
      -  253  0
                   } else if (nextLine.startsWith(CRITICALITY)) {
      -  254  0
                       addCriticalityToVulnerability(parentName, vulnerability, nextLine);
      -  255  0
                   } else if (nextLine.startsWith("URL: ")) {
      -  256  0
                       addReferenceToVulnerability(parentName, vulnerability, nextLine);
      -  257  0
                   } else if (nextLine.startsWith("Description:")) {
      -  258  0
                       appendToDescription = true;
      -  259  0
                       if (null != vulnerability) {
      -  260  0
                           vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 indicates unknown). See link below for full details. *** ");
      -  261   -
                       }
      -  262  0
                   } else if (appendToDescription) {
      -  263  0
                       if (null != vulnerability) {
      -  264  0
                           vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n");
      -  265   -
                       }
      -  266   +  248  0
                   }
      +  249  0
                   if (failed) {
      +  250  0
                       LOGGER.warn("Did not find " + className + '.');
      +  251  
                   }
      -  267  0
               }
      -  268  0
           }
      -  269   -
       
      -  270   -
           private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) {
      -  271  0
               final String advisory = nextLine.substring((ADVISORY.length()));
      -  272  0
               if (null != vulnerability) {
      -  273  0
                   vulnerability.setName(advisory);
      -  274   +  252  0
                   needToDisableGemspecAnalyzer = false;
      +  253  
               }
      -  275  0
               if (null != dependency) {
      -  276  0
                   dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE
      -  277   -
               }
      -  278  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  279  0
           }
      +  254  0
               final File parentFile = dependency.getActualFile().getParentFile();
      +  255  0
               final Process process = launchBundleAudit(parentFile);
      +  256   +
               try {
      +  257  0
                   process.waitFor();
      +  258  0
               } catch (InterruptedException ie) {
      +  259  0
                   throw new AnalysisException("bundle-audit process interrupted", ie);
      +  260  0
               }
      +  261  0
               BufferedReader rdr = null;
      +  262  0
               BufferedReader errReader = null;
      +  263   +
               try {
      +  264  0
                   errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
      +  265  0
                   while (errReader.ready()) {
      +  266  0
                       final String error = errReader.readLine();
      +  267  0
                       LOGGER.warn(error);
      +  268  0
                   }
      +  269  0
                   rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
      +  270  0
                   processBundlerAuditOutput(dependency, engine, rdr);
      +  271  0
               } catch (IOException ioe) {
      +  272  0
                   LOGGER.warn("bundle-audit failure", ioe);
      +  273   +
               } finally {
      +  274  0
                   if (errReader != null) {
      +  275   +
                       try {
      +  276  0
                           errReader.close();
      +  277  0
                       } catch (IOException ioe) {
      +  278  0
                           LOGGER.warn("bundle-audit close failure", ioe);
      +  279  0
                       }
       280   -
       
      -  281   -
           private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
      -  282  0
               final String url = nextLine.substring(("URL: ").length());
      -  283  0
               if (null != vulnerability) {
      -  284  0
                   Reference ref = new Reference();
      -  285  0
                   ref.setName(vulnerability.getName());
      -  286  0
                   ref.setSource("bundle-audit");
      -  287  0
                   ref.setUrl(url);
      -  288  0
                   vulnerability.getReferences().add(ref);
      -  289   -
               }
      -  290  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  291  0
           }
      -  292   -
       
      -  293   -
           private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
      -  294  0
               if (null != vulnerability) {
      -  295  0
                   final String criticality = nextLine.substring(CRITICALITY.length()).trim();
      -  296  0
                   if ("High".equals(criticality)) {
      -  297  0
                       vulnerability.setCvssScore(8.5f);
      -  298  0
                   } else if ("Medium".equals(criticality)) {
      -  299  0
                       vulnerability.setCvssScore(5.5f);
      -  300  0
                   } else if ("Low".equals(criticality)) {
      -  301  0
                       vulnerability.setCvssScore(2.0f);
      -  302   -
                   } else {
      -  303  0
                       vulnerability.setCvssScore(-1.0f);
      -  304  
                   }
      -  305   +  281  0
                   if (null != rdr) {
      +  282   +
                       try {
      +  283  0
                           rdr.close();
      +  284  0
                       } catch (IOException ioe) {
      +  285  0
                           LOGGER.warn("bundle-audit close failure", ioe);
      +  286  0
                       }
      +  287   +
                   }
      +  288  
               }
      -  306  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  307  0
           }
      -  308   +  289  
       
      -  309   -
           private Vulnerability createVulnerability(String parentName, Dependency dependency, Vulnerability vulnerability, String gem, String nextLine) {
      -  310  0
               if (null != dependency) {
      -  311  0
                   final String version = nextLine.substring(VERSION.length());
      -  312  0
                   dependency.getVersionEvidence().addEvidence(
      -  313   +  290  0
           }
      +  291   +
       
      +  292   +
           /**
      +  293   +
            * Processes the bundler audit output.
      +  294   +
            *
      +  295   +
            * @param original the dependency
      +  296   +
            * @param engine the dependency-check engine
      +  297   +
            * @param rdr the reader of the report
      +  298   +
            * @throws IOException thrown if the report cannot be read.
      +  299   +
            */
      +  300   +
           private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException {
      +  301  0
               final String parentName = original.getActualFile().getParentFile().getName();
      +  302  0
               final String fileName = original.getFileName();
      +  303  0
               final String filePath = original.getFilePath();
      +  304  0
               Dependency dependency = null;
      +  305  0
               Vulnerability vulnerability = null;
      +  306  0
               String gem = null;
      +  307  0
               final Map<String, Dependency> map = new HashMap<String, Dependency>();
      +  308  0
               boolean appendToDescription = false;
      +  309  0
               while (rdr.ready()) {
      +  310  0
                   final String nextLine = rdr.readLine();
      +  311  0
                   if (null == nextLine) {
      +  312  0
                       break;
      +  313  0
                   } else if (nextLine.startsWith(NAME)) {
      +  314  0
                       appendToDescription = false;
      +  315  0
                       gem = nextLine.substring(NAME.length());
      +  316  0
                       if (!map.containsKey(gem)) {
      +  317  0
                           map.put(gem, createDependencyForGem(engine, parentName, fileName, filePath, gem));
      +  318   +
                       }
      +  319  0
                       dependency = map.get(gem);
      +  320  0
                       LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  321  0
                   } else if (nextLine.startsWith(VERSION)) {
      +  322  0
                       vulnerability = createVulnerability(parentName, dependency, gem, nextLine);
      +  323  0
                   } else if (nextLine.startsWith(ADVISORY)) {
      +  324  0
                       setVulnerabilityName(parentName, dependency, vulnerability, nextLine);
      +  325  0
                   } else if (nextLine.startsWith(CRITICALITY)) {
      +  326  0
                       addCriticalityToVulnerability(parentName, vulnerability, nextLine);
      +  327  0
                   } else if (nextLine.startsWith("URL: ")) {
      +  328  0
                       addReferenceToVulnerability(parentName, vulnerability, nextLine);
      +  329  0
                   } else if (nextLine.startsWith("Description:")) {
      +  330  0
                       appendToDescription = true;
      +  331  0
                       if (null != vulnerability) {
      +  332  0
                           vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. "
      +  333   +
                                   + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 "
      +  334   +
                                   + " indicates unknown). See link below for full details. *** ");
      +  335   +
                       }
      +  336  0
                   } else if (appendToDescription) {
      +  337  0
                       if (null != vulnerability) {
      +  338  0
                           vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n");
      +  339   +
                       }
      +  340   +
                   }
      +  341  0
               }
      +  342  0
           }
      +  343   +
       
      +  344   +
           /**
      +  345   +
            * Sets the vulnerability name.
      +  346   +
            *
      +  347   +
            * @param parentName the parent name
      +  348   +
            * @param dependency the dependency
      +  349   +
            * @param vulnerability the vulnerability
      +  350   +
            * @param nextLine the line to parse
      +  351   +
            */
      +  352   +
           private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) {
      +  353  0
               final String advisory = nextLine.substring((ADVISORY.length()));
      +  354  0
               if (null != vulnerability) {
      +  355  0
                   vulnerability.setName(advisory);
      +  356   +
               }
      +  357  0
               if (null != dependency) {
      +  358  0
                   dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE
      +  359   +
               }
      +  360  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  361  0
           }
      +  362   +
       
      +  363   +
           /**
      +  364   +
            * Adds a reference to the vulnerability.
      +  365   +
            *
      +  366   +
            * @param parentName the parent name
      +  367   +
            * @param vulnerability the vulnerability
      +  368   +
            * @param nextLine the line to parse
      +  369   +
            */
      +  370   +
           private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
      +  371  0
               final String url = nextLine.substring(("URL: ").length());
      +  372  0
               if (null != vulnerability) {
      +  373  0
                   final Reference ref = new Reference();
      +  374  0
                   ref.setName(vulnerability.getName());
      +  375  0
                   ref.setSource("bundle-audit");
      +  376  0
                   ref.setUrl(url);
      +  377  0
                   vulnerability.getReferences().add(ref);
      +  378   +
               }
      +  379  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  380  0
           }
      +  381   +
       
      +  382   +
           /**
      +  383   +
            * Adds the criticality to the vulnerability
      +  384   +
            *
      +  385   +
            * @param parentName the parent name
      +  386   +
            * @param vulnerability the vulnerability
      +  387   +
            * @param nextLine the line to parse
      +  388   +
            */
      +  389   +
           private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
      +  390  0
               if (null != vulnerability) {
      +  391  0
                   final String criticality = nextLine.substring(CRITICALITY.length()).trim();
      +  392  0
                   float score = -1.0f;
      +  393  0
                   Vulnerability v = null;
      +  394   +
                   try {
      +  395  0
                       v = cvedb.getVulnerability(vulnerability.getName());
      +  396  0
                   } catch (DatabaseException ex) {
      +  397  0
                       LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName());
      +  398  0
                   }
      +  399  0
                   if (v != null) {
      +  400  0
                       score = v.getCvssScore();
      +  401  0
                   } else if ("High".equalsIgnoreCase(criticality)) {
      +  402  0
                       score = 8.5f;
      +  403  0
                   } else if ("Medium".equalsIgnoreCase(criticality)) {
      +  404  0
                       score = 5.5f;
      +  405  0
                   } else if ("Low".equalsIgnoreCase(criticality)) {
      +  406  0
                       score = 2.0f;
      +  407   +
                   }
      +  408  0
                   vulnerability.setCvssScore(score);
      +  409   +
               }
      +  410  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  411  0
           }
      +  412   +
       
      +  413   +
           /**
      +  414   +
            * Creates a vulnerability.
      +  415   +
            *
      +  416   +
            * @param parentName the parent name
      +  417   +
            * @param dependency the dependency
      +  418   +
            * @param gem the gem name
      +  419   +
            * @param nextLine the line to parse
      +  420   +
            * @return the vulnerability
      +  421   +
            */
      +  422   +
           private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) {
      +  423  0
               Vulnerability vulnerability = null;
      +  424  0
               if (null != dependency) {
      +  425  0
                   final String version = nextLine.substring(VERSION.length());
      +  426  0
                   dependency.getVersionEvidence().addEvidence(
      +  427  
                           "bundler-audit",
      -  314   +  428  
                           "Version",
      -  315   +  429  
                           version,
      -  316   +  430  
                           Confidence.HIGHEST);
      -  317  0
                   vulnerability = new Vulnerability(); // don't add to dependency until we have name set later
      -  318  0
                   vulnerability.setMatchedCPE(
      -  319  0
                           String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version),
      -  320   +  431  0
                   vulnerability = new Vulnerability(); // don't add to dependency until we have name set later
      +  432  0
                   vulnerability.setMatchedCPE(
      +  433  0
                           String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version),
      +  434  
                           null);
      -  321  0
                   vulnerability.setCvssAccessVector("-");
      -  322  0
                   vulnerability.setCvssAccessComplexity("-");
      -  323  0
                   vulnerability.setCvssAuthentication("-");
      -  324  0
                   vulnerability.setCvssAvailabilityImpact("-");
      -  325  0
                   vulnerability.setCvssConfidentialityImpact("-");
      -  326  0
                   vulnerability.setCvssIntegrityImpact("-");
      -  327   +  435  0
                   vulnerability.setCvssAccessVector("-");
      +  436  0
                   vulnerability.setCvssAccessComplexity("-");
      +  437  0
                   vulnerability.setCvssAuthentication("-");
      +  438  0
                   vulnerability.setCvssAvailabilityImpact("-");
      +  439  0
                   vulnerability.setCvssConfidentialityImpact("-");
      +  440  0
                   vulnerability.setCvssIntegrityImpact("-");
      +  441  
               }
      -  328  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  329  0
               return vulnerability;
      -  330   +  442  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  443  0
               return vulnerability;
      +  444  
           }
      -  331   +  445  
       
      -  332   -
           private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String gem) throws IOException {
      -  333  0
               final File tempFile = File.createTempFile("Gemfile-" + gem, ".lock", Settings.getTempDirectory());
      -  334  0
               final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem);
      -  335  0
               FileUtils.write(tempFile, displayFileName); // unique contents to avoid dependency bundling
      -  336  0
               final Dependency dependency = new Dependency(tempFile);
      -  337  0
               dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST);
      -  338  0
               dependency.setDisplayFileName(displayFileName);
      -  339  0
               engine.getDependencies().add(dependency);
      -  340  0
               return dependency;
      -  341   +  446   +
           /**
      +  447   +
            * Creates the dependency based off of the gem.
      +  448   +
            *
      +  449   +
            * @param engine the engine used for scanning
      +  450   +
            * @param parentName the gem parent
      +  451   +
            * @param fileName the file name
      +  452   +
            * @param filePath the file path
      +  453   +
            * @param gem the gem name
      +  454   +
            * @return the dependency to add
      +  455   +
            * @throws IOException thrown if a temporary gem file could not be written
      +  456   +
            */
      +  457   +
           private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException {
      +  458  0
               final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock");
      +  459  0
               gemFile.createNewFile();
      +  460  0
               final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem);
      +  461   +
       
      +  462  0
               FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling
      +  463  0
               final Dependency dependency = new Dependency(gemFile);
      +  464  0
               dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST);
      +  465  0
               dependency.setDisplayFileName(displayFileName);
      +  466  0
               dependency.setFileName(fileName);
      +  467  0
               dependency.setFilePath(filePath);
      +  468  0
               engine.getDependencies().add(dependency);
      +  469  0
               return dependency;
      +  470  
           }
      -  342   +  471  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer.html new file mode 100644 index 000000000..a1d5799ae --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer.html @@ -0,0 +1,272 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer
      +
       
      + + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      RubyBundlerAnalyzer
      66%
      20/30
      43%
      13/30
      4.5
      RubyBundlerAnalyzer$1
      100%
      2/2
      N/A
      4.5
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       3  
        *
       4  
        * Licensed under the Apache License, Version 2.0 (the "License");
       5  
        * you may not use this file except in compliance with the License.
       6  
        * You may obtain a copy of the License at
       7  
        *
       8  
        *     http://www.apache.org/licenses/LICENSE-2.0
       9  
        *
       10  
        * Unless required by applicable law or agreed to in writing, software
       11  
        * distributed under the License is distributed on an "AS IS" BASIS,
       12  
        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       13  
        * See the License for the specific language governing permissions and
       14  
        * limitations under the License.
       15  
        *
       16  
        * Copyright (c) 2016 Bianca Jiang. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.analyzer;
       19  
       
       20  
       import java.io.File;
       21  
       import java.io.FilenameFilter;
       22  
       
       23  
       import org.owasp.dependencycheck.Engine;
       24  
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
       25  
       import org.owasp.dependencycheck.dependency.Dependency;
       26  
       
       27  
       /**
       28  
        * This analyzer accepts the fully resolved .gemspec created by the Ruby bundler
       29  
        * (http://bundler.io) for better evidence results. It also tries to resolve the
       30  
        * dependency packagePath to where the gem is actually installed. Then during {@link org.owasp.dependencycheck.analyzer.AnalysisPhase#PRE_FINDING_ANALYSIS}
       31  
        * {@link DependencyBundlingAnalyzer} will merge two .gemspec dependencies
       32  
        * together if <code>Dependency.getPackagePath()</code> are the same.
       33  
        *
       34  
        * Ruby bundler creates new .gemspec files under a folder called
       35  
        * "specifications" at deploy time, in addition to the original .gemspec files
       36  
        * from source. The bundler generated .gemspec files always contain fully
       37  
        * resolved attributes thus provide more accurate evidences, whereas the
       38  
        * original .gemspec from source often contain variables for attributes that
       39  
        * can't be used for evidences.
       40  
        *
       41  
        * Note this analyzer share the same
       42  
        * {@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_RUBY_GEMSPEC_ENABLED} as
       43  
        * {@link RubyGemspecAnalyzer}, so it will enabled/disabled with
       44  
        * {@link RubyGemspecAnalyzer}.
       45  
        *
       46  
        * @author Bianca Jiang (biancajiang@gmail.com)
       47  
        */
       48  
       @Experimental
       49  18
       public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
       50  
       
       51  
           /**
       52  
            * The name of the analyzer.
       53  
            */
       54  
           private static final String ANALYZER_NAME = "Ruby Bundler Analyzer";
       55  
       
       56  
           /**
       57  
            * Folder name that contains .gemspec files created by "bundle install"
       58  
            */
       59  
           private static final String SPECIFICATIONS = "specifications";
       60  
       
       61  
           /**
       62  
            * Folder name that contains the gems by "bundle install"
       63  
            */
       64  
           private static final String GEMS = "gems";
       65  
       
       66  
           /**
       67  
            * Returns the name of the analyzer.
       68  
            *
       69  
            * @return the name of the analyzer.
       70  
            */
       71  
           @Override
       72  
           public String getName() {
       73  30
               return ANALYZER_NAME;
       74  
           }
       75  
       
       76  
           /**
       77  
            * Only accept *.gemspec files generated by "bundle install --deployment"
       78  
            * under "specifications" folder.
       79  
            *
       80  
            * @param pathname the path name to test
       81  
            * @return true if the analyzer can process the given file; otherwise false
       82  
            */
       83  
           @Override
       84  
           public boolean accept(File pathname) {
       85  
       
       86  1722
               boolean accepted = super.accept(pathname);
       87  1722
               if (accepted) {
       88  8
                   final File parentDir = pathname.getParentFile();
       89  8
                   accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
       90  
               }
       91  
       
       92  1722
               return accepted;
       93  
           }
       94  
       
       95  
           @Override
       96  
           protected void analyzeFileType(Dependency dependency, Engine engine)
       97  
                   throws AnalysisException {
       98  4
               super.analyzeFileType(dependency, engine);
       99  
       
       100  
               //find the corresponding gem folder for this .gemspec stub by "bundle install --deployment"
       101  4
               final File gemspecFile = dependency.getActualFile();
       102  4
               final String gemFileName = gemspecFile.getName();
       103  4
               final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec"));
       104  4
               final File specificationsDir = gemspecFile.getParentFile();
       105  4
               if (specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
       106  4
                   final File parentDir = specificationsDir.getParentFile();
       107  4
                   if (parentDir != null && parentDir.exists()) {
       108  4
                       final File gemsDir = new File(parentDir, GEMS);
       109  4
                       if (gemsDir.exists()) {
       110  4
                           final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
       111  
                               public boolean accept(File dir, String name) {
       112  4
                                   return name.equals(gemName);
       113  
                               }
       114  
                           });
       115  
       
       116  4
                           if (matchingFiles != null && matchingFiles.length > 0) {
       117  0
                               final String gemPath = matchingFiles[0].getAbsolutePath();
       118  0
                               if (dependency.getActualFilePath().equals(dependency.getFilePath())) {
       119  0
                                   if (gemPath != null) {
       120  0
                                       dependency.setPackagePath(gemPath);
       121  
                                   }
       122  
                               } else {
       123  
                                   //.gemspec's actualFilePath and filePath are different when it's from a compressed file
       124  
                                   //in which case actualFilePath is the temp directory used by decompression.
       125  
                                   //packagePath should use the filePath of the identified gem file in "gems" folder
       126  0
                                   final File gemspecStub = new File(dependency.getFilePath());
       127  0
                                   final File specDir = gemspecStub.getParentFile();
       128  0
                                   if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
       129  0
                                       final File gemsDir2 = new File(specDir.getParentFile(), GEMS);
       130  0
                                       final File packageDir = new File(gemsDir2, gemName);
       131  0
                                       dependency.setPackagePath(packageDir.getAbsolutePath());
       132  
                                   }
       133  
                               }
       134  
                           }
       135  
                       }
       136  
                   }
       137  
               }
       138  4
           }
       139  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.html index 8f07fa39a..77a248268 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.html @@ -12,7 +12,8 @@
       
      - + +
      Classes in this File Line Coverage Branch Coverage Complexity
      RubyGemspecAnalyzer
      93%
      42/45
      60%
      6/10
      1.875
      RubyGemspecAnalyzer
      76%
      49/64
      40%
      8/20
      2.3
      RubyGemspecAnalyzer$1
      0%
      0/2
      N/A
      2.3
       
      @@ -56,246 +57,392 @@  19  
       
       20   -
       import org.apache.commons.io.FileUtils;
      +
       import java.io.File;
       21   -
       import org.owasp.dependencycheck.Engine;
      +
       import java.io.FileFilter;
       22   -
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      +
       import java.io.FilenameFilter;
       23   -
       import org.owasp.dependencycheck.dependency.Confidence;
      +
       import java.io.IOException;
       24   -
       import org.owasp.dependencycheck.dependency.Dependency;
      +
       import java.nio.charset.Charset;
       25   -
       import org.owasp.dependencycheck.dependency.EvidenceCollection;
      +
       import java.util.List;
       26   -
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      +
       import java.util.regex.Matcher;
       27   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import java.util.regex.Pattern;
       28  
       
       29   -
       import java.io.FileFilter;
      +
       import org.apache.commons.io.FileUtils;
       30   -
       import java.io.IOException;
      +
       import org.owasp.dependencycheck.Engine;
       31   -
       import java.util.regex.Matcher;
      +
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
       32   -
       import java.util.regex.Pattern;
      +
       import org.owasp.dependencycheck.dependency.Confidence;
       33   -
       
      +
       import org.owasp.dependencycheck.dependency.Dependency;
       34   -
       /**
      +
       import org.owasp.dependencycheck.dependency.EvidenceCollection;
       35   -
        * Used to analyze Ruby Gem specifications and collect information that can be used to determine the associated CPE. Regular
      +
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
       36   -
        * expressions are used to parse the well-defined Ruby syntax that forms the specification.
      +
       import org.owasp.dependencycheck.utils.Settings;
       37   -
        *
      +
       import org.slf4j.Logger;
       38   -
        * @author Dale Visser
      +
       import org.slf4j.LoggerFactory;
       39   -
        */
      -  40  7
       public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
      +
       
      +  40   +
       /**
       41   -
       
      +
        * Used to analyze Ruby Gem specifications and collect information that can be
       42   -
           /**
      +
        * used to determine the associated CPE. Regular expressions are used to parse
       43   -
            * The name of the analyzer.
      +
        * the well-defined Ruby syntax that forms the specification.
       44   -
            */
      +
        *
       45   -
           private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer";
      +
        * @author Dale Visser
       46   -
       
      +
        */
       47   -
           /**
      -  48   -
            * The phase that this analyzer is intended to run in.
      +
       @Experimental
      +  48  36
       public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
       49   -
            */
      -  50  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +
       
      +  50   +
           /**
       51   -
       
      +
            * The logger.
       52   -
           private static final String GEMSPEC = "gemspec";
      -  53   -
       
      +
            */
      +  53  2
           private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class);
       54   -
           private static final FileFilter FILTER
      -  55  1
                   = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
      +
           /**
      +  55   +
            * The name of the analyzer.
       56   -
       
      +
            */
       57   -
           private static final String EMAIL = "email";
      +
           private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer";
       58  
       
       59  
           /**
       60   -
            * @return a filter that accepts files named Rakefile or matching the glob pattern, *.gemspec
      +
            * The phase that this analyzer is intended to run in.
       61  
            */
      -  62   -
           @Override
      +  62  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       63   -
           protected FileFilter getFileFilter() {
      -  64  855
               return FILTER;
      -  65   -
           }
      -  66  
       
      -  67   -
           @Override
      -  68   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      -  69   -
               // NO-OP
      -  70  3
           }
      -  71   -
       
      -  72   +  64  
           /**
      -  73   -
            * Returns the name of the analyzer.
      -  74   -
            *
      -  75   -
            * @return the name of the analyzer.
      -  76   +  65   +
            * The gemspec file extension.
      +  66  
            */
      +  67   +
           private static final String GEMSPEC = "gemspec";
      +  68   +
       
      +  69   +
           /**
      +  70   +
            * The file filter containing the list of file extensions that can be
      +  71   +
            * analyzed.
      +  72   +
            */
      +  73  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build();
      +  74   +
           //TODO: support Rakefile
      +  75   +
           //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
      +  76   +
       
       77   -
           @Override
      +
           /**
       78   -
           public String getName() {
      -  79  5
               return ANALYZER_NAME;
      +
            * The name of the version file.
      +  79   +
            */
       80   -
           }
      +
           private static final String VERSION_FILE_NAME = "VERSION";
       81  
       
       82  
           /**
       83   -
            * Returns the phase that the analyzer is intended to run in.
      +
            * @return a filter that accepts files matching the glob pattern, *.gemspec
       84   -
            *
      +
            */
       85   -
            * @return the phase that the analyzer is intended to run in.
      +
           @Override
       86   -
            */
      -  87   -
           @Override
      +
           protected FileFilter getFileFilter() {
      +  87  3442
               return FILTER;
       88   -
           public AnalysisPhase getAnalysisPhase() {
      -  89  3
               return ANALYSIS_PHASE;
      +
           }
      +  89   +
       
       90   -
           }
      +
           @Override
       91   -
       
      +
           protected void initializeFileTypeAnalyzer() throws Exception {
       92   -
           /**
      -  93   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +
               // NO-OP
      +  93  16
           }
       94   -
            *
      +
       
       95   -
            * @return the analyzer's enabled property setting key
      -  96   -
            */
      -  97   -
           @Override
      -  98   -
           protected String getAnalyzerEnabledSettingKey() {
      -  99  7
               return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED;
      -  100   -
           }
      -  101   -
       
      -  102  
           /**
      -  103   -
            * The capture group #1 is the block variable.
      -  104   +  96   +
            * Returns the name of the analyzer.
      +  97   +
            *
      +  98   +
            * @return the name of the analyzer.
      +  99  
            */
      -  105  2
           private static final Pattern GEMSPEC_BLOCK_INIT
      -  106  1
                   = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
      -  107   -
       
      -  108   +  100  
           @Override
      -  109   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  110   -
                   throws AnalysisException {
      -  111   -
               String contents;
      -  112   -
               try {
      -  113  1
                   contents = FileUtils.readFileToString(dependency.getActualFile());
      -  114  0
               } catch (IOException e) {
      -  115  0
                   throw new AnalysisException(
      -  116   -
                           "Problem occurred while reading dependency file.", e);
      -  117  1
               }
      -  118  1
               final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents);
      -  119  1
               if (matcher.find()) {
      -  120  1
                   contents = contents.substring(matcher.end());
      -  121  1
                   final String blockVariable = matcher.group(1);
      -  122  1
                   final EvidenceCollection vendor = dependency.getVendorEvidence();
      -  123  1
                   addStringEvidence(vendor, contents, blockVariable, "author", Confidence.HIGHEST);
      -  124  1
                   addListEvidence(vendor, contents, blockVariable, "authors", Confidence.HIGHEST);
      -  125  1
                   final String email = addStringEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
      -  126  1
                   if (email.isEmpty()) {
      -  127  0
                       addListEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
      -  128   -
                   }
      -  129  1
                   addStringEvidence(vendor, contents, blockVariable, "homepage", Confidence.MEDIUM);
      -  130  1
                   final EvidenceCollection product = dependency.getProductEvidence();
      -  131  1
                   final String name = addStringEvidence(product, contents, blockVariable, "name", Confidence.HIGHEST);
      -  132  1
                   if (!name.isEmpty()) {
      -  133  1
                       vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW);
      -  134   -
                   }
      -  135  1
                   addStringEvidence(product, contents, blockVariable, "summary", Confidence.LOW);
      -  136  1
                   addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", Confidence.HIGHEST);
      -  137   -
               }
      -  138  1
           }
      -  139   -
       
      -  140   -
           private void addListEvidence(EvidenceCollection evidences, String contents,
      -  141   -
                   String blockVariable, String field, Confidence confidence) {
      -  142  2
               final Matcher matcher = Pattern.compile(
      -  143  2
                       String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents);
      -  144  1
               if (matcher.find()) {
      -  145  1
                   final String value = matcher.group(1).replaceAll("['\"]", " ").trim();
      -  146  1
                   evidences.addEvidence(GEMSPEC, field, value, confidence);
      -  147   -
               }
      -  148  1
           }
      -  149   -
       
      -  150   -
           private String addStringEvidence(EvidenceCollection evidences, String contents,
      -  151   -
                   String blockVariable, String field, Confidence confidence) {
      -  152  12
               final Matcher matcher = Pattern.compile(
      -  153  12
                       String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents);
      -  154  6
               String value = "";
      -  155  6
               if (matcher.find()) {
      -  156  5
                   value = matcher.group(2);
      -  157  5
                   evidences.addEvidence(GEMSPEC, field, value, confidence);
      -  158   -
               }
      -  159  6
               return value;
      -  160   +  101   +
           public String getName() {
      +  102  30
               return ANALYZER_NAME;
      +  103  
           }
      -  161   +  104   +
       
      +  105   +
           /**
      +  106   +
            * Returns the phase that the analyzer is intended to run in.
      +  107   +
            *
      +  108   +
            * @return the phase that the analyzer is intended to run in.
      +  109   +
            */
      +  110   +
           @Override
      +  111   +
           public AnalysisPhase getAnalysisPhase() {
      +  112  16
               return ANALYSIS_PHASE;
      +  113   +
           }
      +  114   +
       
      +  115   +
           /**
      +  116   +
            * Returns the key used in the properties file to reference the analyzer's
      +  117   +
            * enabled property.
      +  118   +
            *
      +  119   +
            * @return the analyzer's enabled property setting key
      +  120   +
            */
      +  121   +
           @Override
      +  122   +
           protected String getAnalyzerEnabledSettingKey() {
      +  123  36
               return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED;
      +  124   +
           }
      +  125   +
       
      +  126   +
           /**
      +  127   +
            * The capture group #1 is the block variable.
      +  128   +
            */
      +  129  2
           private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
      +  130   +
       
      +  131   +
           @Override
      +  132   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  133   +
                   throws AnalysisException {
      +  134   +
               String contents;
      +  135   +
               try {
      +  136  8
                   contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset());
      +  137  0
               } catch (IOException e) {
      +  138  0
                   throw new AnalysisException(
      +  139   +
                           "Problem occurred while reading dependency file.", e);
      +  140  8
               }
      +  141  8
               final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents);
      +  142  8
               if (matcher.find()) {
      +  143  8
                   contents = contents.substring(matcher.end());
      +  144  8
                   final String blockVariable = matcher.group(1);
      +  145   +
       
      +  146  8
                   final EvidenceCollection vendor = dependency.getVendorEvidence();
      +  147  8
                   final EvidenceCollection product = dependency.getProductEvidence();
      +  148  8
                   final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST);
      +  149  8
                   if (!name.isEmpty()) {
      +  150  8
                       vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW);
      +  151   +
                   }
      +  152  8
                   addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.LOW);
      +  153   +
       
      +  154  8
                   addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST);
      +  155  8
                   addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM);
      +  156  8
                   addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
      +  157  8
                   addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
      +  158   +
       
      +  159  8
                   final String value = addStringEvidence(dependency.getVersionEvidence(), contents,
      +  160   +
                           blockVariable, "version", "version", Confidence.HIGHEST);
      +  161  8
                   if (value.length() < 1) {
      +  162  0
                       addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence());
      +  163   +
                   }
      +  164   +
               }
      +  165   +
       
      +  166  8
               setPackagePath(dependency);
      +  167  8
           }
      +  168   +
       
      +  169   +
           /**
      +  170   +
            * Adds the specified evidence to the given evidence collection.
      +  171   +
            *
      +  172   +
            * @param evidences the collection to add the evidence to
      +  173   +
            * @param contents the evidence contents
      +  174   +
            * @param blockVariable the variable
      +  175   +
            * @param field the field
      +  176   +
            * @param fieldPattern the field pattern
      +  177   +
            * @param confidence the confidence of the evidence
      +  178   +
            * @return the evidence string value added
      +  179   +
            */
      +  180   +
           private String addStringEvidence(EvidenceCollection evidences, String contents,
      +  181   +
                   String blockVariable, String field, String fieldPattern, Confidence confidence) {
      +  182  56
               String value = "";
      +  183   +
       
      +  184   +
               //capture array value between [ ]
      +  185  112
               final Matcher arrayMatcher = Pattern.compile(
      +  186  112
                       String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
      +  187  56
               if (arrayMatcher.find()) {
      +  188  22
                   final String arrayValue = arrayMatcher.group(1);
      +  189  22
                   value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes
      +  190  22
               } else { //capture single value between quotes
      +  191  68
                   final Matcher matcher = Pattern.compile(
      +  192  68
                           String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
      +  193  34
                   if (matcher.find()) {
      +  194  34
                       value = matcher.group(2);
      +  195   +
                   }
      +  196   +
               }
      +  197  56
               if (value.length() > 0) {
      +  198  56
                   evidences.addEvidence(GEMSPEC, field, value, confidence);
      +  199   +
               }
      +  200   +
       
      +  201  56
               return value;
      +  202   +
           }
      +  203   +
       
      +  204   +
           /**
      +  205   +
            * Adds evidence from the version file.
      +  206   +
            *
      +  207   +
            * @param dependencyFile the dependency being analyzed
      +  208   +
            * @param versionEvidences the version evidence
      +  209   +
            */
      +  210   +
           private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) {
      +  211  0
               final File parentDir = dependencyFile.getParentFile();
      +  212  0
               if (parentDir != null) {
      +  213  0
                   final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() {
      +  214   +
                       public boolean accept(File dir, String name) {
      +  215  0
                           return name.contains(VERSION_FILE_NAME);
      +  216   +
                       }
      +  217   +
                   });
      +  218  0
                   for (File f : matchingFiles) {
      +  219   +
                       try {
      +  220  0
                           final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset());
      +  221  0
                           if (lines.size() == 1) { //TODO other checking?
      +  222  0
                               final String value = lines.get(0).trim();
      +  223  0
                               versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH);
      +  224   +
                           }
      +  225  0
                       } catch (IOException e) {
      +  226  0
                           LOGGER.debug("Error reading gemspec", e);
      +  227  0
                       }
      +  228   +
                   }
      +  229   +
               }
      +  230  0
           }
      +  231   +
       
      +  232   +
           /**
      +  233   +
            * Sets the package path on the dependency.
      +  234   +
            *
      +  235   +
            * @param dep the dependency to alter
      +  236   +
            */
      +  237   +
           private void setPackagePath(Dependency dep) {
      +  238  8
               final File file = new File(dep.getFilePath());
      +  239  8
               final String parent = file.getParent();
      +  240  8
               if (parent != null) {
      +  241  8
                   dep.setPackagePath(parent);
      +  242   +
               }
      +  243  8
           }
      +  244  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer.html index 59e756b97..ded91cd37 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer.html @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  4
       public class VulnerabilitySuppressionAnalyzer extends AbstractSuppressionAnalyzer {
      +  31  12
       public class VulnerabilitySuppressionAnalyzer extends AbstractSuppressionAnalyzer {
       32  
       
       33   @@ -96,7 +96,7 @@
            * The phase that this analyzer is intended to run in.
       40  
            */
      -  41  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_FINDING_ANALYSIS;
      +  41  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_FINDING_ANALYSIS;
       42  
       
       43   @@ -113,7 +113,7 @@
           @Override
       49  
           public String getName() {
      -  50  4
               return ANALYZER_NAME;
      +  50  32
               return ANALYZER_NAME;
       51  
           }
       52   @@ -132,7 +132,7 @@
           @Override
       59  
           public AnalysisPhase getAnalysisPhase() {
      -  60  3
               return ANALYSIS_PHASE;
      +  60  8
               return ANALYSIS_PHASE;
       61  
           }
       62   @@ -145,20 +145,20 @@
           public void analyze(final Dependency dependency, final Engine engine) throws AnalysisException {
       66  
       
      -  67  2
               if (getRules() == null || getRules().size() <= 0) {
      +  67  8
               if (getRules() == null || getRules().size() <= 0) {
       68  0
                   return;
       69  
               }
       70  
       
      -  71  2
               for (final SuppressionRule rule : getRules()) {
      -  72  84
                   rule.process(dependency);
      -  73  84
               }
      -  74  2
           }
      +  71  8
               for (final SuppressionRule rule : getRules()) {
      +  72  440
                   rule.process(dependency);
      +  73  440
               }
      +  74  8
           }
       75  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.AnalysisException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.AnalysisException.html index 523b80d31..d3227fc9f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.AnalysisException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.AnalysisException.html @@ -103,8 +103,8 @@
            */
       44  
           public AnalysisException(String msg) {
      -  45  1
               super(msg);
      -  46  1
           }
      +  45  2
               super(msg);
      +  46  2
           }
       47  
       
       48   @@ -137,12 +137,12 @@
            */
       63  
           public AnalysisException(String msg, Throwable ex) {
      -  64  2
               super(msg, ex);
      -  65  2
           }
      +  64  8
               super(msg, ex);
      +  65  8
           }
       66  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException.html index ff78d6158..0cd43b97f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException.html @@ -143,6 +143,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.central.CentralSearch.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.central.CentralSearch.html index f35fb0af5..4880dda23 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.central.CentralSearch.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.central.CentralSearch.html @@ -133,7 +133,7 @@
            * Used for logging.
       58  
            */
      -  59  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CentralSearch.class);
      +  59  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CentralSearch.class);
       60  
       
       61   @@ -148,18 +148,18 @@
            * end in /select)
       66  
            */
      -  67  5
           public CentralSearch(URL rootURL) {
      -  68  5
               this.rootURL = rootURL;
      -  69  5
               if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) {
      +  67  10
           public CentralSearch(URL rootURL) {
      +  68  10
               this.rootURL = rootURL;
      +  69  10
               if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) {
       70  0
                   useProxy = true;
       71  0
                   LOGGER.debug("Using proxy");
       72  
               } else {
      -  73  5
                   useProxy = false;
      -  74  5
                   LOGGER.debug("Not using proxy");
      +  73  10
                   useProxy = false;
      +  74  10
                   LOGGER.debug("Not using proxy");
       75  
               }
      -  76  5
           }
      +  76  10
           }
       77  
       
       78   @@ -180,16 +180,16 @@
            */
       86  
           public List<MavenArtifact> searchSha1(String sha1) throws IOException {
      -  87  5
               if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
      -  88  2
                   throw new IllegalArgumentException("Invalid SHA1 format");
      +  87  10
               if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
      +  88  4
                   throw new IllegalArgumentException("Invalid SHA1 format");
       89  
               }
       90  
       
      -  91  3
               final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
      +  91  6
               final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
       92  
       
      -  93  3
               LOGGER.debug("Searching Central url {}", url);
      +  93  6
               LOGGER.debug("Searching Central url {}", url);
       94  
       
       95   @@ -200,62 +200,62 @@
               // 2) Otherwise, don't use the proxy (either the proxy isn't configured,
       98  
               // or proxy is specifically set to false)
      -  99  3
               final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
      +  99  6
               final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
       100  
       
      -  101  3
               conn.setDoOutput(true);
      +  101  6
               conn.setDoOutput(true);
       102  
       
       103  
               // JSON would be more elegant, but there's not currently a dependency
       104  
               // on JSON, so don't want to add one just for this
      -  105  3
               conn.addRequestProperty("Accept", "application/xml");
      -  106  3
               conn.connect();
      +  105  6
               conn.addRequestProperty("Accept", "application/xml");
      +  106  6
               conn.connect();
       107  
       
      -  108  3
               if (conn.getResponseCode() == 200) {
      -  109  3
                   boolean missing = false;
      +  108  6
               if (conn.getResponseCode() == 200) {
      +  109  6
                   boolean missing = false;
       110  
                   try {
       111  
                       final DocumentBuilder builder = DocumentBuilderFactory
      -  112  3
                               .newInstance().newDocumentBuilder();
      -  113  3
                       final Document doc = builder.parse(conn.getInputStream());
      -  114  3
                       final XPath xpath = XPathFactory.newInstance().newXPath();
      -  115  3
                       final String numFound = xpath.evaluate("/response/result/@numFound", doc);
      -  116  3
                       if ("0".equals(numFound)) {
      -  117  1
                           missing = true;
      +  112  6
                               .newInstance().newDocumentBuilder();
      +  113  6
                       final Document doc = builder.parse(conn.getInputStream());
      +  114  6
                       final XPath xpath = XPathFactory.newInstance().newXPath();
      +  115  6
                       final String numFound = xpath.evaluate("/response/result/@numFound", doc);
      +  116  6
                       if ("0".equals(numFound)) {
      +  117  2
                           missing = true;
       118  
                       } else {
      -  119  2
                           final List<MavenArtifact> result = new ArrayList<MavenArtifact>();
      -  120  2
                           final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
      -  121  5
                           for (int i = 0; i < docs.getLength(); i++) {
      -  122  3
                               final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
      -  123  3
                               LOGGER.trace("GroupId: {}", g);
      -  124  3
                               final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
      -  125  3
                               LOGGER.trace("ArtifactId: {}", a);
      -  126  3
                               final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
      -  127  3
                               NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
      -  128  3
                               boolean pomAvailable = false;
      -  129  3
                               boolean jarAvailable = false;
      -  130  14
                               for (int x = 0; x < atts.getLength(); x++) {
      -  131  11
                                   final String tmp = xpath.evaluate(".", atts.item(x));
      -  132  11
                                   if (".pom".equals(tmp)) {
      -  133  3
                                       pomAvailable = true;
      -  134  8
                                   } else if (".jar".equals(tmp)) {
      -  135  3
                                       jarAvailable = true;
      +  119  4
                           final List<MavenArtifact> result = new ArrayList<MavenArtifact>();
      +  120  4
                           final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
      +  121  10
                           for (int i = 0; i < docs.getLength(); i++) {
      +  122  6
                               final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
      +  123  6
                               LOGGER.trace("GroupId: {}", g);
      +  124  6
                               final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
      +  125  6
                               LOGGER.trace("ArtifactId: {}", a);
      +  126  6
                               final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
      +  127  6
                               NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
      +  128  6
                               boolean pomAvailable = false;
      +  129  6
                               boolean jarAvailable = false;
      +  130  28
                               for (int x = 0; x < atts.getLength(); x++) {
      +  131  22
                                   final String tmp = xpath.evaluate(".", atts.item(x));
      +  132  22
                                   if (".pom".equals(tmp)) {
      +  133  6
                                       pomAvailable = true;
      +  134  16
                                   } else if (".jar".equals(tmp)) {
      +  135  6
                                       jarAvailable = true;
       136  
                                   }
       137  
                               }
       138  
       
      -  139  3
                               atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
      -  140  3
                               boolean useHTTPS = false;
      -  141  21
                               for (int x = 0; x < atts.getLength(); x++) {
      -  142  18
                                   final String tmp = xpath.evaluate(".", atts.item(x));
      -  143  18
                                   if ("https".equals(tmp)) {
      +  139  6
                               atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
      +  140  6
                               boolean useHTTPS = false;
      +  141  42
                               for (int x = 0; x < atts.getLength(); x++) {
      +  142  36
                                   final String tmp = xpath.evaluate(".", atts.item(x));
      +  143  36
                                   if ("https".equals(tmp)) {
       144  0
                                       useHTTPS = true;
       145  
                                   }
      @@ -263,13 +263,13 @@
                               }
       147  
       
      -  148  3
                               LOGGER.trace("Version: {}", v);
      -  149  3
                               result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
      +  148  6
                               LOGGER.trace("Version: {}", v);
      +  149  6
                               result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
       150  
                           }
       151  
       
      -  152  2
                           return result;
      +  152  4
                           return result;
       153  
                       }
       154  0
                   } catch (Throwable e) {
      @@ -278,11 +278,11 @@  156  
                       // from well
       157  0
                       throw new IOException(e.getMessage(), e);
      -  158  1
                   }
      +  158  2
                   }
       159  
       
      -  160  1
                   if (missing) {
      -  161  1
                       throw new FileNotFoundException("Artifact not found in Central");
      +  160  2
                   if (missing) {
      +  161  2
                       throw new FileNotFoundException("Artifact not found in Central");
       162  
                   }
       163  0
               } else {
      @@ -300,6 +300,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerDependency.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerDependency.html index c92139680..c2c755b05 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerDependency.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerDependency.html @@ -113,11 +113,11 @@
            * @param version the version
       48  
            */
      -  49  61
           public ComposerDependency(String group, String project, String version) {
      -  50  61
               this.group = group;
      -  51  61
               this.project = project;
      -  52  61
               this.version = version;
      -  53  61
           }
      +  49  122
           public ComposerDependency(String group, String project, String version) {
      +  50  122
               this.group = group;
      +  51  122
               this.project = project;
      +  52  122
               this.version = version;
      +  53  122
           }
       54  
       
       55   @@ -132,7 +132,7 @@
            */
       60  
           public String getGroup() {
      -  61  90
               return group;
      +  61  180
               return group;
       62  
           }
       63   @@ -149,7 +149,7 @@
            */
       69  
           public String getProject() {
      -  70  90
               return project;
      +  70  180
               return project;
       71  
           }
       72   @@ -166,7 +166,7 @@
            */
       78  
           public String getVersion() {
      -  79  30
               return version;
      +  79  60
               return version;
       80  
           }
       81   @@ -175,28 +175,28 @@
           @Override
       83  
           public boolean equals(Object o) {
      -  84  28
               if (this == o) {
      +  84  56
               if (this == o) {
       85  0
                   return true;
       86  
               }
      -  87  28
               if (!(o instanceof ComposerDependency)) {
      +  87  56
               if (!(o instanceof ComposerDependency)) {
       88  0
                   return false;
       89  
               }
       90  
       
      -  91  28
               final ComposerDependency that = (ComposerDependency) o;
      +  91  56
               final ComposerDependency that = (ComposerDependency) o;
       92  
       
      -  93  28
               if (group != null ? !group.equals(that.group) : that.group != null) {
      -  94  17
                   return false;
      +  93  56
               if (group != null ? !group.equals(that.group) : that.group != null) {
      +  94  34
                   return false;
       95  
               }
      -  96  11
               if (project != null ? !project.equals(that.project) : that.project != null) {
      -  97  10
                   return false;
      +  96  22
               if (project != null ? !project.equals(that.project) : that.project != null) {
      +  97  20
                   return false;
       98  
               }
      -  99  1
               return !(version != null ? !version.equals(that.version) : that.version != null);
      +  99  2
               return !(version != null ? !version.equals(that.version) : that.version != null);
       100  
       
       101   @@ -217,6 +217,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerException.html index 329f0a2c6..7617cab43 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerException.html @@ -121,12 +121,12 @@
            */
       54  
           public ComposerException(String message, Throwable cause) {
      -  55  3
               super(message, cause);
      -  56  3
           }
      +  55  6
               super(message, cause);
      +  56  6
           }
       57  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerLockParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerLockParser.html index 35dde7426..cff1aeda4 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerLockParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerLockParser.html @@ -131,7 +131,7 @@
            * The LOGGER
       57  
            */
      -  58  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockParser.class);
      +  58  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockParser.class);
       59  
       
       60   @@ -144,12 +144,12 @@
            * @param inputStream the InputStream to parse
       64  
            */
      -  65  5
           public ComposerLockParser(InputStream inputStream) {
      -  66  5
               LOGGER.info("Creating a ComposerLockParser");
      -  67  5
               this.inputStream = inputStream;
      -  68  5
               this.jsonReader = Json.createReader(inputStream);
      -  69  5
               this.composerDependencies = new ArrayList<ComposerDependency>();
      -  70  5
           }
      +  65  10
           public ComposerLockParser(InputStream inputStream) {
      +  66  10
               LOGGER.info("Creating a ComposerLockParser");
      +  67  10
               this.inputStream = inputStream;
      +  68  10
               this.jsonReader = Json.createReader(inputStream);
      +  69  10
               this.composerDependencies = new ArrayList<ComposerDependency>();
      +  70  10
           }
       71  
       
       72   @@ -160,30 +160,30 @@
            */
       75  
           public void process() {
      -  76  5
               LOGGER.info("Beginning Composer lock processing");
      +  76  10
               LOGGER.info("Beginning Composer lock processing");
       77  
               try {
      -  78  5
                   final JsonObject composer = jsonReader.readObject();
      -  79  3
                   if (composer.containsKey("packages")) {
      -  80  3
                       LOGGER.debug("Found packages");
      -  81  3
                       final JsonArray packages = composer.getJsonArray("packages");
      -  82  2
                       for (JsonObject pkg : packages.getValuesAs(JsonObject.class)) {
      -  83  60
                           if (pkg.containsKey("name")) {
      -  84  60
                               final String groupName = pkg.getString("name");
      -  85  60
                               if (groupName.indexOf('/') >= 0 && groupName.indexOf('/') <= groupName.length() - 1) {
      -  86  60
                                   if (pkg.containsKey("version")) {
      -  87  60
                                       final String group = groupName.substring(0, groupName.indexOf('/'));
      -  88  60
                                       final String project = groupName.substring(groupName.indexOf('/') + 1);
      -  89  60
                                       String version = pkg.getString("version");
      +  78  10
                   final JsonObject composer = jsonReader.readObject();
      +  79  6
                   if (composer.containsKey("packages")) {
      +  80  6
                       LOGGER.debug("Found packages");
      +  81  6
                       final JsonArray packages = composer.getJsonArray("packages");
      +  82  4
                       for (JsonObject pkg : packages.getValuesAs(JsonObject.class)) {
      +  83  120
                           if (pkg.containsKey("name")) {
      +  84  120
                               final String groupName = pkg.getString("name");
      +  85  120
                               if (groupName.indexOf('/') >= 0 && groupName.indexOf('/') <= groupName.length() - 1) {
      +  86  120
                                   if (pkg.containsKey("version")) {
      +  87  120
                                       final String group = groupName.substring(0, groupName.indexOf('/'));
      +  88  120
                                       final String project = groupName.substring(groupName.indexOf('/') + 1);
      +  89  120
                                       String version = pkg.getString("version");
       90  
                                       // Some version nubmers begin with v - which doesn't end up matching CPE's
      -  91  60
                                       if (version.startsWith("v")) {
      -  92  42
                                           version = version.substring(1);
      +  91  120
                                       if (version.startsWith("v")) {
      +  92  84
                                           version = version.substring(1);
       93  
                                       }
      -  94  60
                                       LOGGER.debug("Got package {}/{}/{}", group, project, version);
      -  95  60
                                       composerDependencies.add(new ComposerDependency(group, project, version));
      -  96  60
                                   } else {
      +  94  120
                                       LOGGER.debug("Got package {}/{}/{}", group, project, version);
      +  95  120
                                       composerDependencies.add(new ComposerDependency(group, project, version));
      +  96  120
                                   } else {
       97  0
                                       LOGGER.debug("Group/package {} does not have a version", groupName);
       98  
                                   }
      @@ -194,19 +194,19 @@
                               }
       102  
                           }
      -  103  60
                       }
      +  103  120
                       }
       104  
                   }
      -  105  1
               } catch (JsonParsingException jsonpe) {
      -  106  1
                   throw new ComposerException("Error parsing stream", jsonpe);
      -  107  1
               } catch (JsonException jsone) {
      -  108  1
                   throw new ComposerException("Error reading stream", jsone);
      +  105  2
               } catch (JsonParsingException jsonpe) {
      +  106  2
                   throw new ComposerException("Error parsing stream", jsonpe);
      +  107  2
               } catch (JsonException jsone) {
      +  108  2
                   throw new ComposerException("Error reading stream", jsone);
       109  0
               } catch (IllegalStateException ise) {
       110  0
                   throw new ComposerException("Illegal state in composer stream", ise);
      -  111  1
               } catch (ClassCastException cce) {
      -  112  1
                   throw new ComposerException("Not exactly composer lock", cce);
      -  113  2
               }
      -  114  2
           }
      +  111  2
               } catch (ClassCastException cce) {
      +  112  2
                   throw new ComposerException("Not exactly composer lock", cce);
      +  113  4
               }
      +  114  4
           }
       115  
       
       116   @@ -221,13 +221,13 @@
            */
       121  
           public List<ComposerDependency> getDependencies() {
      -  122  3
               return composerDependencies;
      +  122  6
               return composerDependencies;
       123  
           }
       124  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.CpeMemoryIndex.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.CpeMemoryIndex.html index 2d263e0e2..760b9d2c2 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.CpeMemoryIndex.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.CpeMemoryIndex.html @@ -137,14 +137,14 @@
            * The logger.
       60  
            */
      -  61  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class);
      +  61  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class);
       62  
           /**
       63  
            * singleton instance.
       64  
            */
      -  65  1
           private static final CpeMemoryIndex INSTANCE = new CpeMemoryIndex();
      +  65  2
           private static final CpeMemoryIndex INSTANCE = new CpeMemoryIndex();
       66  
       
       67   @@ -153,8 +153,8 @@
            * private constructor for singleton.
       69  
            */
      -  70  1
           private CpeMemoryIndex() {
      -  71  1
           }
      +  70  2
           private CpeMemoryIndex() {
      +  71  2
           }
       72  
       
       73   @@ -169,7 +169,7 @@
            */
       78  
           public static CpeMemoryIndex getInstance() {
      -  79  1
               return INSTANCE;
      +  79  4
               return INSTANCE;
       80  
           }
       81   @@ -244,31 +244,31 @@
            */
       116  
           public void open(CveDB cve) throws IndexException {
      -  117  1
               synchronized (INSTANCE) {
      -  118  1
                   if (!openState) {
      -  119  1
                       index = new RAMDirectory();
      -  120  1
                       buildIndex(cve);
      +  117  4
               synchronized (INSTANCE) {
      +  118  4
                   if (!openState) {
      +  119  4
                       index = new RAMDirectory();
      +  120  4
                       buildIndex(cve);
       121  
                       try {
      -  122  1
                           indexReader = DirectoryReader.open(index);
      +  122  4
                           indexReader = DirectoryReader.open(index);
       123  0
                       } catch (IOException ex) {
       124  0
                           throw new IndexException(ex);
      -  125  1
                       }
      -  126  1
                       indexSearcher = new IndexSearcher(indexReader);
      -  127  1
                       searchingAnalyzer = createSearchingAnalyzer();
      -  128  1
                       queryParser = new QueryParser(LuceneUtils.CURRENT_VERSION, Fields.DOCUMENT_KEY, searchingAnalyzer);
      -  129  1
                       openState = true;
      +  125  4
                       }
      +  126  4
                       indexSearcher = new IndexSearcher(indexReader);
      +  127  4
                       searchingAnalyzer = createSearchingAnalyzer();
      +  128  4
                       queryParser = new QueryParser(LuceneUtils.CURRENT_VERSION, Fields.DOCUMENT_KEY, searchingAnalyzer);
      +  129  4
                       openState = true;
       130  
                   }
      -  131  1
               }
      -  132  1
           }
      +  131  4
               }
      +  132  4
           }
       133  
           /**
       134  
            * A flag indicating whether or not the index is open.
       135  
            */
      -  136  1
           private boolean openState = false;
      +  136  2
           private boolean openState = false;
       137  
       
       138   @@ -300,9 +300,9 @@
            */
       152  
           private Analyzer createIndexingAnalyzer() {
      -  153  1
               final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
      -  154  1
               fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
      -  155  1
               return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
      +  153  4
               final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
      +  154  4
               fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
      +  155  4
               return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
       156  
           }
       157   @@ -319,15 +319,15 @@
            */
       163  
           private Analyzer createSearchingAnalyzer() {
      -  164  1
               final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
      -  165  1
               fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
      -  166  1
               productSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
      -  167  1
               vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
      -  168  1
               fieldAnalyzers.put(Fields.PRODUCT, productSearchFieldAnalyzer);
      -  169  1
               fieldAnalyzers.put(Fields.VENDOR, vendorSearchFieldAnalyzer);
      +  164  4
               final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
      +  165  4
               fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
      +  166  4
               productSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
      +  167  4
               vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
      +  168  4
               fieldAnalyzers.put(Fields.PRODUCT, productSearchFieldAnalyzer);
      +  169  4
               fieldAnalyzers.put(Fields.VENDOR, vendorSearchFieldAnalyzer);
       170  
       
      -  171  1
               return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
      +  171  4
               return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
       172  
           }
       173   @@ -340,30 +340,30 @@
            */
       177  
           public void close() {
      -  178  1
               if (searchingAnalyzer != null) {
      -  179  1
                   searchingAnalyzer.close();
      -  180  1
                   searchingAnalyzer = null;
      +  178  4
               if (searchingAnalyzer != null) {
      +  179  4
                   searchingAnalyzer.close();
      +  180  4
                   searchingAnalyzer = null;
       181  
               }
      -  182  1
               if (indexReader != null) {
      +  182  4
               if (indexReader != null) {
       183  
                   try {
      -  184  1
                       indexReader.close();
      +  184  4
                       indexReader.close();
       185  0
                   } catch (IOException ex) {
       186  0
                       LOGGER.trace("", ex);
      -  187  1
                   }
      -  188  1
                   indexReader = null;
      +  187  4
                   }
      +  188  4
                   indexReader = null;
       189  
               }
      -  190  1
               queryParser = null;
      -  191  1
               indexSearcher = null;
      -  192  1
               if (index != null) {
      -  193  1
                   index.close();
      -  194  1
                   index = null;
      +  190  4
               queryParser = null;
      +  191  4
               indexSearcher = null;
      +  192  4
               if (index != null) {
      +  193  4
                   index.close();
      +  194  4
                   index = null;
       195  
               }
      -  196  1
               openState = false;
      -  197  1
           }
      +  196  4
               openState = false;
      +  197  4
           }
       198  
       
       199   @@ -380,13 +380,13 @@
            */
       205  
           private void buildIndex(CveDB cve) throws IndexException {
      -  206  1
               Analyzer analyzer = null;
      -  207  1
               IndexWriter indexWriter = null;
      +  206  4
               Analyzer analyzer = null;
      +  207  4
               IndexWriter indexWriter = null;
       208  
               try {
      -  209  1
                   analyzer = createIndexingAnalyzer();
      -  210  1
                   final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer);
      -  211  1
                   indexWriter = new IndexWriter(index, conf);
      +  209  4
                   analyzer = createIndexingAnalyzer();
      +  210  4
                   final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer);
      +  211  4
                   indexWriter = new IndexWriter(index, conf);
       212  
                   try {
       213   @@ -395,53 +395,53 @@
                       // See "Re-use Document and Field instances" from
       215  
                       // http://wiki.apache.org/lucene-java/ImproveIndexingSpeed
      -  216  1
                       final Document doc = new Document();
      -  217  1
                       final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES);
      -  218  1
                       final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES);
      -  219  1
                       doc.add(v);
      -  220  1
                       doc.add(p);
      +  216  4
                       final Document doc = new Document();
      +  217  4
                       final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES);
      +  218  4
                       final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES);
      +  219  4
                       doc.add(v);
      +  220  4
                       doc.add(p);
       221  
       
      -  222  1
                       final Set<Pair<String, String>> data = cve.getVendorProductList();
      -  223  1
                       for (Pair<String, String> pair : data) {
      -  224  25715
                           v.setStringValue(pair.getLeft());
      -  225  25715
                           p.setStringValue(pair.getRight());
      -  226  25715
                           indexWriter.addDocument(doc);
      -  227  25715
                       }
      +  222  4
                       final Set<Pair<String, String>> data = cve.getVendorProductList();
      +  223  4
                       for (Pair<String, String> pair : data) {
      +  224  103668
                           v.setStringValue(pair.getLeft());
      +  225  103668
                           p.setStringValue(pair.getRight());
      +  226  103668
                           indexWriter.addDocument(doc);
      +  227  103668
                       }
       228  0
                   } catch (DatabaseException ex) {
       229  0
                       LOGGER.debug("", ex);
       230  0
                       throw new IndexException("Error reading CPE data", ex);
      -  231  1
                   }
      +  231  4
                   }
       232  0
               } catch (CorruptIndexException ex) {
       233  0
                   throw new IndexException("Unable to close an in-memory index", ex);
       234  0
               } catch (IOException ex) {
       235  0
                   throw new IndexException("Unable to close an in-memory index", ex);
       236  
               } finally {
      -  237  1
                   if (indexWriter != null) {
      +  237  4
                   if (indexWriter != null) {
       238  
                       try {
       239  
                           try {
      -  240  1
                               indexWriter.commit();
      +  240  4
                               indexWriter.commit();
       241  
                           } finally {
      -  242  1
                               indexWriter.close(true);
      -  243  1
                           }
      +  242  4
                               indexWriter.close(true);
      +  243  4
                           }
       244  0
                       } catch (CorruptIndexException ex) {
       245  0
                           throw new IndexException("Unable to close an in-memory index", ex);
       246  0
                       } catch (IOException ex) {
       247  0
                           throw new IndexException("Unable to close an in-memory index", ex);
      -  248  1
                       }
      -  249  1
                       if (analyzer != null) {
      -  250  1
                           analyzer.close();
      +  248  4
                       }
      +  249  4
                       if (analyzer != null) {
      +  250  4
                           analyzer.close();
       251  
                       }
       252  
                   }
       253  
               }
      -  254  1
           }
      +  254  4
           }
       255  
       
       256   @@ -452,15 +452,15 @@
            */
       259  
           private void resetSearchingAnalyzer() {
      -  260  6
               if (productSearchFieldAnalyzer != null) {
      -  261  6
                   productSearchFieldAnalyzer.clear();
      +  260  22
               if (productSearchFieldAnalyzer != null) {
      +  261  22
                   productSearchFieldAnalyzer.clear();
       262  
               }
      -  263  6
               if (vendorSearchFieldAnalyzer != null) {
      -  264  6
                   vendorSearchFieldAnalyzer.clear();
      +  263  22
               if (vendorSearchFieldAnalyzer != null) {
      +  264  22
                   vendorSearchFieldAnalyzer.clear();
       265  
               }
      -  266  6
           }
      +  266  22
           }
       267  
       
       268   @@ -483,13 +483,13 @@
            */
       277  
           public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException {
      -  278  6
               if (searchString == null || searchString.trim().isEmpty()) {
      +  278  22
               if (searchString == null || searchString.trim().isEmpty()) {
       279  0
                   throw new ParseException("Query is null or empty");
       280  
               }
      -  281  6
               LOGGER.debug(searchString);
      -  282  6
               final Query query = queryParser.parse(searchString);
      -  283  6
               return search(query, maxQueryResults);
      +  281  22
               LOGGER.debug(searchString);
      +  282  22
               final Query query = queryParser.parse(searchString);
      +  283  22
               return search(query, maxQueryResults);
       284  
           }
       285   @@ -514,8 +514,8 @@
            */
       295  
           public TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException {
      -  296  6
               resetSearchingAnalyzer();
      -  297  6
               return indexSearcher.search(query, maxQueryResults);
      +  296  22
               resetSearchingAnalyzer();
      +  297  22
               return indexSearcher.search(query, maxQueryResults);
       298  
           }
       299   @@ -564,6 +564,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.Fields.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.Fields.html index 4b830c1c4..b9132d16a 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.Fields.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.Fields.html @@ -107,6 +107,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexEntry.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexEntry.html index 4801d7a4c..41297f58d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexEntry.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexEntry.html @@ -73,7 +73,7 @@
        * @author Jeremy Long
       28  
        */
      -  29  1578
       public class IndexEntry implements Serializable {
      +  29  3274
       public class IndexEntry implements Serializable {
       30  
       
       31   @@ -151,7 +151,7 @@
            */
       70  
           public String getVendor() {
      -  71  30
               return vendor;
      +  71  62
               return vendor;
       72  
           }
       73   @@ -168,8 +168,8 @@
            */
       79  
           public void setVendor(String vendor) {
      -  80  1577
               this.vendor = vendor;
      -  81  1577
           }
      +  80  3278
               this.vendor = vendor;
      +  81  3278
           }
       82  
           /**
       83   @@ -192,7 +192,7 @@
            */
       92  
           public String getProduct() {
      -  93  110
               return product;
      +  93  132
               return product;
       94  
           }
       95   @@ -209,8 +209,8 @@
            */
       101  
           public void setProduct(String product) {
      -  102  1577
               this.product = product;
      -  103  1577
           }
      +  102  3276
               this.product = product;
      +  103  3276
           }
       104  
           /**
       105   @@ -290,19 +290,19 @@
            */
       144  
           public void parseName(String cpeName) throws UnsupportedEncodingException {
      -  145  1
               if (cpeName != null && cpeName.length() > 7) {
      -  146  1
                   final String[] data = cpeName.substring(7).split(":");
      -  147  1
                   if (data.length >= 1) {
      -  148  1
                       vendor = URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8");
      -  149  1
                       if (data.length >= 2) {
      -  150  1
                           product = URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8");
      +  145  2
               if (cpeName != null && cpeName.length() > 7) {
      +  146  2
                   final String[] data = cpeName.substring(7).split(":");
      +  147  2
                   if (data.length >= 1) {
      +  148  2
                       vendor = URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8");
      +  149  2
                       if (data.length >= 2) {
      +  150  2
                           product = URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8");
       151  
                       }
       152  
                   }
       153  
               }
      -  154  1
           }
      +  154  2
           }
       155  
       
       156   @@ -320,21 +320,21 @@
           @Override
       164  
           public boolean equals(Object obj) {
      -  165  951
               if (obj == null) {
      +  165  708
               if (obj == null) {
       166  0
                   return false;
       167  
               }
      -  168  951
               if (getClass() != obj.getClass()) {
      +  168  708
               if (getClass() != obj.getClass()) {
       169  0
                   return false;
       170  
               }
      -  171  951
               final IndexEntry other = (IndexEntry) obj;
      -  172  951
               if ((this.vendor == null) ? (other.vendor != null) : !this.vendor.equals(other.vendor)) {
      -  173  934
                   return false;
      +  171  708
               final IndexEntry other = (IndexEntry) obj;
      +  172  708
               if ((this.vendor == null) ? (other.vendor != null) : !this.vendor.equals(other.vendor)) {
      +  173  690
                   return false;
       174  
               }
      -  175  17
               if ((this.product == null) ? (other.product != null) : !this.product.equals(other.product)) {
      -  176  17
                   return false;
      +  175  18
               if ((this.product == null) ? (other.product != null) : !this.product.equals(other.product)) {
      +  176  18
                   return false;
       177  
               }
       178  0
               return true;
      @@ -363,6 +363,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexException.html index 1cd8ed576..fde2206ef 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexException.html @@ -143,6 +143,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweDB.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweDB.html index 4ce6face8..080a9be61 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweDB.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweDB.html @@ -91,7 +91,7 @@
            * The Logger.
       37  
            */
      -  38  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CweDB.class);
      +  38  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CweDB.class);
       39  
       
       40   @@ -110,7 +110,7 @@
            * A HashMap of the CWE data.
       48  
            */
      -  49  1
           private static final Map<String, String> CWE = loadData();
      +  49  2
           private static final Map<String, String> CWE = loadData();
       50  
       
       51   @@ -125,16 +125,16 @@
            */
       56  
           private static Map<String, String> loadData() {
      -  57  1
               ObjectInputStream oin = null;
      +  57  2
               ObjectInputStream oin = null;
       58  
               try {
      -  59  1
                   final String filePath = "data/cwe.hashmap.serialized";
      -  60  1
                   final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
      -  61  1
                   oin = new ObjectInputStream(input);
      +  59  2
                   final String filePath = "data/cwe.hashmap.serialized";
      +  60  2
                   final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
      +  61  2
                   oin = new ObjectInputStream(input);
       62  
                   @SuppressWarnings("unchecked")
      -  63  1
                   final Map<String, String> ret = (HashMap<String, String>) oin.readObject();
      -  64  1
                   return ret;
      +  63  2
                   final Map<String, String> ret = (HashMap<String, String>) oin.readObject();
      +  64  4
                   return ret;
       65  0
               } catch (ClassNotFoundException ex) {
       66  0
                   LOGGER.warn("Unable to load CWE data. This should not be an issue.");
       67  0
                   LOGGER.debug("", ex);
      @@ -143,10 +143,10 @@  70  0
                   LOGGER.debug("", ex);
       71  
               } finally {
      -  72  1
                   if (oin != null) {
      +  72  2
                   if (oin != null) {
       73  
                       try {
      -  74  1
                           oin.close();
      +  74  2
                           oin.close();
       75  0
                       } catch (IOException ex) {
       76  0
                           LOGGER.trace("", ex);
       77  2
                       }
      @@ -175,8 +175,8 @@
            */
       90  
           public static String getCweName(String cweId) {
      -  91  9
               if (cweId != null) {
      -  92  9
                   return CWE.get(cweId);
      +  91  18
               if (cweId != null) {
      +  92  18
                   return CWE.get(cweId);
       93  
               }
       94  0
               return null;
      @@ -186,6 +186,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweHandler.html index 61d97b0ab..0bb5a1bca 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweHandler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweHandler.html @@ -121,6 +121,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter.html index 594d22b1a..14ddafc54 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter.html @@ -85,7 +85,7 @@
            * The char term attribute.
       34  
            */
      -  35  11
           private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
      +  35  25
           private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
       36  
       
       37   @@ -100,7 +100,7 @@
            */
       42  
           protected CharTermAttribute getTermAtt() {
      -  43  32391
               return termAtt;
      +  43  59324
               return termAtt;
       44  
           }
       45   @@ -125,7 +125,7 @@
            */
       55  
           protected LinkedList<String> getTokens() {
      -  56  32377
               return tokens;
      +  56  59312
               return tokens;
       57  
           }
       58   @@ -142,9 +142,9 @@
            */
       64  
           public AbstractTokenizingFilter(TokenStream stream) {
      -  65  11
               super(stream);
      -  66  11
               tokens = new LinkedList<String>();
      -  67  11
           }
      +  65  25
               super(stream);
      +  66  25
               tokens = new LinkedList<String>();
      +  67  25
           }
       68  
       
       69   @@ -159,20 +159,20 @@
            */
       74  
           protected boolean addTerm() {
      -  75  32217
               final boolean termAdded = !tokens.isEmpty();
      -  76  32246
               if (termAdded) {
      -  77  21838
                   final String term = tokens.pop();
      -  78  21836
                   clearAttributes();
      -  79  21837
                   termAtt.append(term);
      +  75  59187
               final boolean termAdded = !tokens.isEmpty();
      +  76  59187
               if (termAdded) {
      +  77  39863
                   final String term = tokens.pop();
      +  78  39861
                   clearAttributes();
      +  79  39873
                   termAtt.append(term);
       80  
               }
      -  81  32271
               return termAdded;
      +  81  59182
               return termAdded;
       82  
           }
       83  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer.html index 64f53821f..b93fde078 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer.html @@ -91,8 +91,8 @@
            */
       37  
           public AlphaNumericTokenizer(Version matchVersion, Reader in) {
      -  38  7
               super(matchVersion, in);
      -  39  7
           }
      +  38  22
               super(matchVersion, in);
      +  39  22
           }
       40  
       
       41   @@ -131,13 +131,13 @@
           @Override
       59  
           protected boolean isTokenChar(int c) {
      -  60  617221
               return Character.isLetter(c) || Character.isDigit(c);
      +  60  2489074
               return Character.isLetter(c) || Character.isDigit(c);
       61  
           }
       62  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.DependencySimilarity.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.DependencySimilarity.html index 55d3f1c96..03a7b1137 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.DependencySimilarity.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.DependencySimilarity.html @@ -111,6 +111,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.FieldAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.FieldAnalyzer.html index e7bba8436..373c8b55d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.FieldAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.FieldAnalyzer.html @@ -113,9 +113,9 @@
            * @param version the Lucene version
       48  
            */
      -  49  3
           public FieldAnalyzer(Version version) {
      -  50  3
               this.version = version;
      -  51  3
           }
      +  49  10
           public FieldAnalyzer(Version version) {
      +  50  10
               this.version = version;
      +  51  10
           }
       52  
       
       53   @@ -136,13 +136,13 @@
           @Override
       61  
           protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
      -  62  3
               final Tokenizer source = new AlphaNumericTokenizer(version, reader);
      +  62  10
               final Tokenizer source = new AlphaNumericTokenizer(version, reader);
       63  
       
      -  64  3
               TokenStream stream = source;
      +  64  10
               TokenStream stream = source;
       65  
       
      -  66  3
               stream = new WordDelimiterFilter(stream,
      +  66  10
               stream = new WordDelimiterFilter(stream,
       67  
                       WordDelimiterFilter.CATENATE_WORDS
       68   @@ -159,17 +159,17 @@
                       | WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null);
       74  
       
      -  75  3
               stream = new LowerCaseFilter(version, stream);
      -  76  3
               stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
      +  75  10
               stream = new LowerCaseFilter(version, stream);
      +  76  10
               stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
       77  
       
      -  78  3
               return new TokenStreamComponents(source, stream);
      +  78  10
               return new TokenStreamComponents(source, stream);
       79  
           }
       80  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.LuceneUtils.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.LuceneUtils.html index 097b70744..89095ee8f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.LuceneUtils.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.LuceneUtils.html @@ -85,7 +85,7 @@
            * base.
       34  
            */
      -  35  1
           public static final Version CURRENT_VERSION = Version.LUCENE_47;
      +  35  2
           public static final Version CURRENT_VERSION = Version.LUCENE_47;
       36  
       
       37   @@ -124,15 +124,15 @@
                   final CharSequence text) {
       55  
       
      -  56  106
               if (text == null || buf == null) {
      -  57  1
                   return;
      +  56  232
               if (text == null || buf == null) {
      +  57  2
                   return;
       58  
               }
       59  
       
      -  60  980
               for (int i = 0; i < text.length(); i++) {
      -  61  875
                   final char c = text.charAt(i);
      -  62  875
                   switch (c) {
      +  60  2950
               for (int i = 0; i < text.length(); i++) {
      +  61  2720
                   final char c = text.charAt(i);
      +  62  2720
                   switch (c) {
       63  
                       case '+':
       64   @@ -171,17 +171,17 @@
                       case '/':
       81  
                       case '\\': //it is supposed to fall through here
      -  82  58
                           buf.append('\\');
      +  82  116
                           buf.append('\\');
       83  
                       default:
      -  84  875
                           buf.append(c);
      +  84  2720
                           buf.append(c);
       85  
                           break;
       86  
                   }
       87  
               }
      -  88  105
           }
      +  88  230
           }
       89  
       
       90   @@ -198,20 +198,20 @@
            */
       96  
           public static String escapeLuceneQuery(final CharSequence text) {
      -  97  2
               if (text == null) {
      -  98  1
                   return null;
      +  97  4
               if (text == null) {
      +  98  2
                   return null;
       99  
               }
      -  100  1
               final int size = text.length() << 1;
      -  101  1
               final StringBuilder buf = new StringBuilder(size);
      -  102  1
               appendEscapedLuceneQuery(buf, text);
      -  103  1
               return buf.toString();
      +  100  2
               final int size = text.length() << 1;
      +  101  2
               final StringBuilder buf = new StringBuilder(size);
      +  102  2
               appendEscapedLuceneQuery(buf, text);
      +  103  2
               return buf.toString();
       104  
           }
       105  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer.html index aaf8101cc..0a685ec92 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer.html @@ -117,9 +117,9 @@
            * @param version the Lucene version
       50  
            */
      -  51  4
           public SearchFieldAnalyzer(Version version) {
      -  52  4
               this.version = version;
      -  53  4
           }
      +  51  12
           public SearchFieldAnalyzer(Version version) {
      +  52  12
               this.version = version;
      +  53  12
           }
       54  
       
       55   @@ -140,13 +140,13 @@
           @Override
       63  
           protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
      -  64  4
               final Tokenizer source = new AlphaNumericTokenizer(version, reader);
      +  64  12
               final Tokenizer source = new AlphaNumericTokenizer(version, reader);
       65  
       
      -  66  4
               TokenStream stream = source;
      +  66  12
               TokenStream stream = source;
       67  
       
      -  68  4
               stream = new WordDelimiterFilter(stream,
      +  68  12
               stream = new WordDelimiterFilter(stream,
       69  
                       WordDelimiterFilter.GENERATE_WORD_PARTS
       70   @@ -161,14 +161,14 @@
                       | WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null);
       75  
       
      -  76  4
               stream = new LowerCaseFilter(version, stream);
      -  77  4
               stream = new UrlTokenizingFilter(stream);
      -  78  4
               concatenatingFilter = new TokenPairConcatenatingFilter(stream);
      -  79  4
               stream = concatenatingFilter;
      -  80  4
               stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
      +  76  12
               stream = new LowerCaseFilter(version, stream);
      +  77  12
               stream = new UrlTokenizingFilter(stream);
      +  78  12
               concatenatingFilter = new TokenPairConcatenatingFilter(stream);
      +  79  12
               stream = concatenatingFilter;
      +  80  12
               stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
       81  
       
      -  82  4
               return new TokenStreamComponents(source, stream);
      +  82  12
               return new TokenStreamComponents(source, stream);
       83  
           }
       84   @@ -187,15 +187,15 @@
            */
       91  
           public void clear() {
      -  92  14
               if (concatenatingFilter != null) {
      -  93  14
                   concatenatingFilter.clear();
      +  92  48
               if (concatenatingFilter != null) {
      +  93  48
                   concatenatingFilter.clear();
       94  
               }
      -  95  14
           }
      +  95  48
           }
       96  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter.html index cbbe5559a..8022ef45f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter.html @@ -93,7 +93,7 @@
            * The char term attribute.
       38  
            */
      -  39  6
           private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
      +  39  16
           private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
       40  
           /**
       41   @@ -124,7 +124,7 @@
            */
       54  
           protected String getPreviousWord() {
      -  55  2
               return previousWord;
      +  55  4
               return previousWord;
       56  
           }
       57   @@ -141,7 +141,7 @@
            */
       63  
           protected LinkedList<String> getWords() {
      -  64  1
               return words;
      +  64  2
               return words;
       65  
           }
       66   @@ -158,9 +158,9 @@
            */
       72  
           public TokenPairConcatenatingFilter(TokenStream stream) {
      -  73  6
               super(stream);
      -  74  6
               words = new LinkedList<String>();
      -  75  6
           }
      +  73  16
               super(stream);
      +  74  16
               words = new LinkedList<String>();
      +  75  16
           }
       76  
       
       77   @@ -185,35 +185,35 @@
       
       87  
               //collect all the terms into the words collection
      -  88  656
               while (input.incrementToken()) {
      -  89  188
                   final String word = new String(termAtt.buffer(), 0, termAtt.length());
      -  90  188
                   words.add(word);
      -  91  188
               }
      +  88  1906
               while (input.incrementToken()) {
      +  89  536
                   final String word = new String(termAtt.buffer(), 0, termAtt.length());
      +  90  536
                   words.add(word);
      +  91  536
               }
       92  
       
       93  
               //if we have a previousTerm - write it out as its own token concatenated
       94  
               // with the current word (if one is available).
      -  95  468
               if (previousWord != null && !words.isEmpty()) {
      -  96  170
                   final String word = words.getFirst();
      -  97  170
                   clearAttributes();
      -  98  170
                   termAtt.append(previousWord).append(word);
      -  99  170
                   previousWord = null;
      -  100  170
                   return true;
      +  95  1370
               if (previousWord != null && !words.isEmpty()) {
      +  96  480
                   final String word = words.getFirst();
      +  97  480
                   clearAttributes();
      +  98  480
                   termAtt.append(previousWord).append(word);
      +  99  480
                   previousWord = null;
      +  100  480
                   return true;
       101  
               }
       102  
               //if we have words, write it out as a single token
      -  103  298
               if (!words.isEmpty()) {
      -  104  188
                   final String word = words.removeFirst();
      -  105  188
                   clearAttributes();
      -  106  188
                   termAtt.append(word);
      -  107  188
                   previousWord = word;
      -  108  188
                   return true;
      +  103  890
               if (!words.isEmpty()) {
      +  104  536
                   final String word = words.removeFirst();
      +  105  536
                   clearAttributes();
      +  106  536
                   termAtt.append(word);
      +  107  536
                   previousWord = word;
      +  108  536
                   return true;
       109  
               }
      -  110  110
               return false;
      +  110  354
               return false;
       111  
           }
       112   @@ -232,9 +232,9 @@
            */
       119  
           public void clear() {
      -  120  15
               previousWord = null;
      -  121  15
               words.clear();
      -  122  15
           }
      +  120  50
               previousWord = null;
      +  121  50
               words.clear();
      +  122  50
           }
       123  
       
       124   @@ -306,6 +306,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter.html index fb0af3422..7a1742c92 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter.html @@ -101,7 +101,7 @@
            * The logger.
       42  
            */
      -  43  1
           private static final Logger LOGGER = LoggerFactory.getLogger(UrlTokenizingFilter.class);
      +  43  2
           private static final Logger LOGGER = LoggerFactory.getLogger(UrlTokenizingFilter.class);
       44  
       
       45   @@ -116,8 +116,8 @@
            */
       50  
           public UrlTokenizingFilter(TokenStream stream) {
      -  51  11
               super(stream);
      -  52  11
           }
      +  51  25
               super(stream);
      +  52  25
           }
       53  
       
       54   @@ -138,22 +138,22 @@
           @Override
       62  
           public boolean incrementToken() throws IOException {
      -  63  32368
               final LinkedList<String> tokens = getTokens();
      -  64  32381
               final CharTermAttribute termAtt = getTermAtt();
      -  65  32391
               if (tokens.isEmpty() && input.incrementToken()) {
      -  66  21826
                   final String text = new String(termAtt.buffer(), 0, termAtt.length());
      -  67  21830
                   if (UrlStringUtils.containsUrl(text)) {
      -  68  6
                       final String[] parts = text.split("\\s");
      -  69  12
                       for (String part : parts) {
      -  70  6
                           if (UrlStringUtils.isUrl(part)) {
      +  63  59271
               final LinkedList<String> tokens = getTokens();
      +  64  59310
               final CharTermAttribute termAtt = getTermAtt();
      +  65  59323
               if (tokens.isEmpty() && input.incrementToken()) {
      +  66  39843
                   final String text = new String(termAtt.buffer(), 0, termAtt.length());
      +  67  39848
                   if (UrlStringUtils.containsUrl(text)) {
      +  68  12
                       final String[] parts = text.split("\\s");
      +  69  24
                       for (String part : parts) {
      +  70  12
                           if (UrlStringUtils.isUrl(part)) {
       71  
                               try {
      -  72  6
                                   final List<String> data = UrlStringUtils.extractImportantUrlData(part);
      -  73  6
                                   tokens.addAll(data);
      +  72  12
                                   final List<String> data = UrlStringUtils.extractImportantUrlData(part);
      +  73  12
                                   tokens.addAll(data);
       74  0
                               } catch (MalformedURLException ex) {
       75  0
                                   LOGGER.debug("error parsing {}", part, ex);
       76  0
                                   tokens.add(part);
      -  77  6
                               }
      +  77  12
                               }
       78  
                           } else {
       79  0
                               tokens.add(part);
      @@ -161,19 +161,19 @@
                           }
       81  
                       }
      -  82  6
                   } else {
      -  83  21819
                       tokens.add(text);
      +  82  12
                   } else {
      +  83  39832
                       tokens.add(text);
       84  
                   }
       85  
               }
      -  86  32212
               return addTerm();
      +  86  59181
               return addTerm();
       87  
           }
       88  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.MavenArtifact.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.MavenArtifact.html index 0392b3740..d4d204b95 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.MavenArtifact.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.MavenArtifact.html @@ -178,36 +178,36 @@
            * @param secureDownload if the jar and pom files should be downloaded using HTTPS.
       84  
            */
      -  85  3
           public MavenArtifact(String groupId, String artifactId, String version, boolean jarAvailable, boolean pomAvailable, boolean secureDownload) {
      -  86  3
               this.groupId = groupId;
      -  87  3
               this.artifactId = artifactId;
      -  88  3
               this.version = version;
      +  85  6
           public MavenArtifact(String groupId, String artifactId, String version, boolean jarAvailable, boolean pomAvailable, boolean secureDownload) {
      +  86  6
               this.groupId = groupId;
      +  87  6
               this.artifactId = artifactId;
      +  88  6
               this.version = version;
       89  
               String base;
      -  90  3
               if (secureDownload) {
      +  90  6
               if (secureDownload) {
       91  0
                   base = "https:" + CENTRAL_CONTENT_URL;
       92  
               } else {
      -  93  3
                   base = "http:" + CENTRAL_CONTENT_URL;
      +  93  6
                   base = "http:" + CENTRAL_CONTENT_URL;
       94  
               }
      -  95  3
               if (jarAvailable) {
      +  95  6
               if (jarAvailable) {
       96  
                   //org/springframework/spring-core/3.2.0.RELEASE/spring-core-3.2.0.RELEASE.pom
      -  97  3
                   this.artifactUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
      +  97  6
                   this.artifactUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
       98  
                           + version + '/' + artifactId + '-' + version + ".jar";
       99  
               }
      -  100  3
               if (pomAvailable) {
      +  100  6
               if (pomAvailable) {
       101  
                   //org/springframework/spring-core/3.2.0.RELEASE/spring-core-3.2.0.RELEASE.pom
      -  102  3
                   this.pomUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
      +  102  6
                   this.pomUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
       103  
                           + version + '/' + artifactId + '-' + version + ".pom";
       104  
               }
      -  105  3
           }
      +  105  6
           }
       106  
       
       107   @@ -226,12 +226,12 @@
            * @param url the artifactLink url
       114  
            */
      -  115  2
           public MavenArtifact(String groupId, String artifactId, String version, String url) {
      -  116  2
               this.groupId = groupId;
      -  117  2
               this.artifactId = artifactId;
      -  118  2
               this.version = version;
      -  119  2
               this.artifactUrl = url;
      -  120  2
           }
      +  115  4
           public MavenArtifact(String groupId, String artifactId, String version, String url) {
      +  116  4
               this.groupId = groupId;
      +  117  4
               this.artifactId = artifactId;
      +  118  4
               this.version = version;
      +  119  4
               this.artifactUrl = url;
      +  120  4
           }
       121  
       
       122   @@ -248,7 +248,7 @@
           @Override
       128  
           public String toString() {
      -  129  1
               return String.format("%s:%s:%s", groupId, artifactId, version);
      +  129  2
               return String.format("%s:%s:%s", groupId, artifactId, version);
       130  
           }
       131   @@ -281,7 +281,7 @@
            */
       146  
           public String getGroupId() {
      -  147  5
               return groupId;
      +  147  10
               return groupId;
       148  
           }
       149   @@ -314,7 +314,7 @@
            */
       164  
           public String getArtifactId() {
      -  165  5
               return artifactId;
      +  165  10
               return artifactId;
       166  
           }
       167   @@ -347,7 +347,7 @@
            */
       182  
           public String getVersion() {
      -  183  5
               return version;
      +  183  10
               return version;
       184  
           }
       185   @@ -380,7 +380,7 @@
            */
       200  
           public String getArtifactUrl() {
      -  201  4
               return artifactUrl;
      +  201  8
               return artifactUrl;
       202  
           }
       203   @@ -426,6 +426,6 @@
       // vim: cc=120:sw=4:ts=4:sts=4
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.NexusSearch.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.NexusSearch.html index 5f1f37193..7360eb387 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.NexusSearch.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.NexusSearch.html @@ -327,6 +327,6 @@
       // vim: cc=120:sw=4:ts=4:sts=4
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NugetPackage.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NugetPackage.html index d8822a204..9dfecdcfc 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NugetPackage.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NugetPackage.html @@ -133,8 +133,8 @@
            * Creates an empty NugetPackage.
       58  
            */
      -  59  2
           public NugetPackage() {
      -  60  2
           }
      +  59  4
           public NugetPackage() {
      +  60  4
           }
       61  
       
       62   @@ -147,8 +147,8 @@
            */
       66  
           public void setId(String id) {
      -  67  1
               this.id = id;
      -  68  1
           }
      +  67  2
               this.id = id;
      +  68  2
           }
       69  
       
       70   @@ -161,7 +161,7 @@
            */
       74  
           public String getId() {
      -  75  1
               return id;
      +  75  2
               return id;
       76  
           }
       77   @@ -176,8 +176,8 @@
            */
       82  
           public void setVersion(String version) {
      -  83  1
               this.version = version;
      -  84  1
           }
      +  83  2
               this.version = version;
      +  84  2
           }
       85  
       
       86   @@ -190,7 +190,7 @@
            */
       90  
           public String getVersion() {
      -  91  1
               return version;
      +  91  2
               return version;
       92  
           }
       93   @@ -205,8 +205,8 @@
            */
       98  
           public void setTitle(String title) {
      -  99  1
               this.title = title;
      -  100  1
           }
      +  99  2
               this.title = title;
      +  100  2
           }
       101  
       
       102   @@ -219,7 +219,7 @@
            */
       106  
           public String getTitle() {
      -  107  1
               return title;
      +  107  2
               return title;
       108  
           }
       109   @@ -234,8 +234,8 @@
            */
       114  
           public void setAuthors(String authors) {
      -  115  1
               this.authors = authors;
      -  116  1
           }
      +  115  2
               this.authors = authors;
      +  116  2
           }
       117  
       
       118   @@ -248,7 +248,7 @@
            */
       122  
           public String getAuthors() {
      -  123  1
               return authors;
      +  123  2
               return authors;
       124  
           }
       125   @@ -263,8 +263,8 @@
            */
       130  
           public void setOwners(String owners) {
      -  131  1
               this.owners = owners;
      -  132  1
           }
      +  131  2
               this.owners = owners;
      +  132  2
           }
       133  
       
       134   @@ -277,7 +277,7 @@
            */
       138  
           public String getOwners() {
      -  139  1
               return owners;
      +  139  2
               return owners;
       140  
           }
       141   @@ -292,8 +292,8 @@
            */
       146  
           public void setLicenseUrl(String licenseUrl) {
      -  147  1
               this.licenseUrl = licenseUrl;
      -  148  1
           }
      +  147  2
               this.licenseUrl = licenseUrl;
      +  148  2
           }
       149  
       
       150   @@ -306,7 +306,7 @@
            */
       154  
           public String getLicenseUrl() {
      -  155  1
               return licenseUrl;
      +  155  2
               return licenseUrl;
       156  
           }
       157   @@ -352,6 +352,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParseException.html index d4d1dfe7f..1c0e2cae2 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParseException.html @@ -113,8 +113,8 @@
            */
       49  
           public NuspecParseException(String message) {
      -  50  1
               super(message);
      -  51  1
           }
      +  50  2
               super(message);
      +  51  2
           }
       52  
       
       53   @@ -141,12 +141,12 @@
            */
       64  
           public NuspecParseException(String message, Throwable cause) {
      -  65  2
               super(message, cause);
      -  66  2
           }
      +  65  4
               super(message, cause);
      +  66  4
           }
       67  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParser.html index 9d367e7b8..5899f0f61 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParser.html @@ -93,6 +93,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.XPathNuspecParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.XPathNuspecParser.html index 5d3d037f0..a1803ef3e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.XPathNuspecParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.XPathNuspecParser.html @@ -81,7 +81,7 @@
        * @author colezlaw
       32  
        */
      -  33  3
       public class XPathNuspecParser implements NuspecParser {
      +  33  6
       public class XPathNuspecParser implements NuspecParser {
       34  
       
       35   @@ -98,8 +98,8 @@
            */
       41  
           private String getOrNull(Node n) {
      -  42  3
               if (n != null) {
      -  43  3
                   return n.getTextContent();
      +  42  6
               if (n != null) {
      +  43  6
                   return n.getTextContent();
       44  
               } else {
       45  0
                   return null;
      @@ -129,29 +129,29 @@
           public NugetPackage parse(InputStream stream) throws NuspecParseException {
       58  
               try {
      -  59  3
                   final Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream);
      -  60  2
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      -  61  2
                   final NugetPackage nuspec = new NugetPackage();
      +  59  6
                   final Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream);
      +  60  4
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      +  61  4
                   final NugetPackage nuspec = new NugetPackage();
       62  
       
      -  63  2
                   if (xpath.evaluate("/package/metadata/id", d, XPathConstants.NODE) == null
      -  64  1
                           || xpath.evaluate("/package/metadata/version", d, XPathConstants.NODE) == null
      -  65  1
                           || xpath.evaluate("/package/metadata/authors", d, XPathConstants.NODE) == null
      -  66  1
                           || xpath.evaluate("/package/metadata/description", d, XPathConstants.NODE) == null) {
      -  67  1
                       throw new NuspecParseException("Invalid Nuspec format");
      +  63  4
                   if (xpath.evaluate("/package/metadata/id", d, XPathConstants.NODE) == null
      +  64  2
                           || xpath.evaluate("/package/metadata/version", d, XPathConstants.NODE) == null
      +  65  2
                           || xpath.evaluate("/package/metadata/authors", d, XPathConstants.NODE) == null
      +  66  2
                           || xpath.evaluate("/package/metadata/description", d, XPathConstants.NODE) == null) {
      +  67  2
                       throw new NuspecParseException("Invalid Nuspec format");
       68  
                   }
       69  
       
      -  70  1
                   nuspec.setId(xpath.evaluate("/package/metadata/id", d));
      -  71  1
                   nuspec.setVersion(xpath.evaluate("/package/metadata/version", d));
      -  72  1
                   nuspec.setAuthors(xpath.evaluate("/package/metadata/authors", d));
      -  73  1
                   nuspec.setOwners(getOrNull((Node) xpath.evaluate("/package/metadata/owners", d, XPathConstants.NODE)));
      -  74  1
                   nuspec.setLicenseUrl(getOrNull((Node) xpath.evaluate("/package/metadata/licenseUrl", d, XPathConstants.NODE)));
      -  75  1
                   nuspec.setTitle(getOrNull((Node) xpath.evaluate("/package/metadata/title", d, XPathConstants.NODE)));
      -  76  1
                   return nuspec;
      -  77  2
               } catch (Throwable e) {
      -  78  2
                   throw new NuspecParseException("Unable to parse nuspec", e);
      +  70  2
                   nuspec.setId(xpath.evaluate("/package/metadata/id", d));
      +  71  2
                   nuspec.setVersion(xpath.evaluate("/package/metadata/version", d));
      +  72  2
                   nuspec.setAuthors(xpath.evaluate("/package/metadata/authors", d));
      +  73  2
                   nuspec.setOwners(getOrNull((Node) xpath.evaluate("/package/metadata/owners", d, XPathConstants.NODE)));
      +  74  2
                   nuspec.setLicenseUrl(getOrNull((Node) xpath.evaluate("/package/metadata/licenseUrl", d, XPathConstants.NODE)));
      +  75  2
                   nuspec.setTitle(getOrNull((Node) xpath.evaluate("/package/metadata/title", d, XPathConstants.NODE)));
      +  76  2
                   return nuspec;
      +  77  4
               } catch (Throwable e) {
      +  78  4
                   throw new NuspecParseException("Unable to parse nuspec", e);
       79  
               }
       80   @@ -160,6 +160,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.ConnectionFactory.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.ConnectionFactory.html index 5ee5cf252..1c56da9b5 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.ConnectionFactory.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.ConnectionFactory.html @@ -113,14 +113,14 @@
            * The Logger.
       48  
            */
      -  49  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionFactory.class);
      +  49  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionFactory.class);
       50  
           /**
       51  
            * The version of the current DB Schema.
       52  
            */
      -  53  1
           public static final String DB_SCHEMA_VERSION = Settings.getString(Settings.KEYS.DB_VERSION);
      +  53  2
           public static final String DB_SCHEMA_VERSION = Settings.getString(Settings.KEYS.DB_VERSION);
       54  
           /**
       55   @@ -151,28 +151,28 @@
            * The database driver used to connect to the database.
       68  
            */
      -  69  1
           private static Driver driver = null;
      +  69  2
           private static Driver driver = null;
       70  
           /**
       71  
            * The database connection string.
       72  
            */
      -  73  1
           private static String connectionString = null;
      +  73  2
           private static String connectionString = null;
       74  
           /**
       75  
            * The username to connect to the database.
       76  
            */
      -  77  1
           private static String userName = null;
      +  77  2
           private static String userName = null;
       78  
           /**
       79  
            * The password for the database.
       80  
            */
      -  81  1
           private static String password = null;
      +  81  2
           private static String password = null;
       82  
       
       83   @@ -201,42 +201,42 @@
           public static synchronized void initialize() throws DatabaseException {
       96  
               //this only needs to be called once.
      -  97  11
               if (connectionString != null) {
      -  98  9
                   return;
      +  97  38
               if (connectionString != null) {
      +  98  34
                   return;
       99  
               }
      -  100  2
               Connection conn = null;
      +  100  4
               Connection conn = null;
       101  
               try {
       102  
                   //load the driver if necessary
      -  103  2
                   final String driverName = Settings.getString(Settings.KEYS.DB_DRIVER_NAME, "");
      -  104  2
                   if (!driverName.isEmpty()) { //likely need to load the correct driver
      -  105  2
                       LOGGER.debug("Loading driver: {}", driverName);
      -  106  2
                       final String driverPath = Settings.getString(Settings.KEYS.DB_DRIVER_PATH, "");
      +  103  4
                   final String driverName = Settings.getString(Settings.KEYS.DB_DRIVER_NAME, "");
      +  104  4
                   if (!driverName.isEmpty()) { //likely need to load the correct driver
      +  105  4
                       LOGGER.debug("Loading driver: {}", driverName);
      +  106  4
                       final String driverPath = Settings.getString(Settings.KEYS.DB_DRIVER_PATH, "");
       107  
                       try {
      -  108  2
                           if (!driverPath.isEmpty()) {
      +  108  4
                           if (!driverPath.isEmpty()) {
       109  0
                               LOGGER.debug("Loading driver from: {}", driverPath);
       110  0
                               driver = DriverLoader.load(driverName, driverPath);
       111  
                           } else {
      -  112  2
                               driver = DriverLoader.load(driverName);
      +  112  4
                               driver = DriverLoader.load(driverName);
       113  
                           }
       114  0
                       } catch (DriverLoadException ex) {
       115  0
                           LOGGER.debug("Unable to load database driver", ex);
       116  0
                           throw new DatabaseException("Unable to load database driver");
      -  117  2
                       }
      +  117  4
                       }
       118  
                   }
      -  119  2
                   userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser");
      +  119  4
                   userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser");
       120  
                   //yes, yes - hard-coded password - only if there isn't one in the properties file.
      -  121  2
                   password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!");
      +  121  4
                   password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!");
       122  
                   try {
      -  123  2
                       connectionString = Settings.getConnectionString(
      +  123  4
                       connectionString = Settings.getConnectionString(
       124  
                               Settings.KEYS.DB_CONNECTION_STRING,
       125   @@ -246,27 +246,27 @@  128  
                               "Unable to retrieve the database connection string", ex);
       129  0
                       throw new DatabaseException("Unable to retrieve the database connection string");
      -  130  2
                   }
      -  131  2
                   boolean shouldCreateSchema = false;
      +  130  4
                   }
      +  131  4
                   boolean shouldCreateSchema = false;
       132  
                   try {
      -  133  2
                       if (connectionString.startsWith("jdbc:h2:file:")) { //H2
      -  134  2
                           shouldCreateSchema = !h2DataFileExists();
      -  135  2
                           LOGGER.debug("Need to create DB Structure: {}", shouldCreateSchema);
      +  133  4
                       if (connectionString.startsWith("jdbc:h2:file:")) { //H2
      +  134  4
                           shouldCreateSchema = !h2DataFileExists();
      +  135  4
                           LOGGER.debug("Need to create DB Structure: {}", shouldCreateSchema);
       136  
                       }
       137  0
                   } catch (IOException ioex) {
       138  0
                       LOGGER.debug("Unable to verify database exists", ioex);
       139  0
                       throw new DatabaseException("Unable to verify database exists");
      -  140  2
                   }
      -  141  2
                   LOGGER.debug("Loading database connection");
      -  142  2
                   LOGGER.debug("Connection String: {}", connectionString);
      -  143  2
                   LOGGER.debug("Database User: {}", userName);
      +  140  4
                   }
      +  141  4
                   LOGGER.debug("Loading database connection");
      +  142  4
                   LOGGER.debug("Connection String: {}", connectionString);
      +  143  4
                   LOGGER.debug("Database User: {}", userName);
       144  
       
       145  
                   try {
      -  146  2
                       conn = DriverManager.getConnection(connectionString, userName, password);
      +  146  4
                       conn = DriverManager.getConnection(connectionString, userName, password);
       147  0
                   } catch (SQLException ex) {
       148  0
                       if (ex.getMessage().contains("java.net.UnknownHostException") && connectionString.contains("AUTO_SERVER=TRUE;")) {
       149  0
                           connectionString = connectionString.replace("AUTO_SERVER=TRUE;", "");
      @@ -287,10 +287,10 @@  161  0
                           throw new DatabaseException("Unable to connect to the database");
       162  
                       }
      -  163  2
                   }
      +  163  4
                   }
       164  
       
      -  165  2
                   if (shouldCreateSchema) {
      +  165  4
                   if (shouldCreateSchema) {
       166  
                       try {
       167  0
                           createTables(conn);
      @@ -302,25 +302,25 @@
                   }
       173  
                   try {
      -  174  2
                       ensureSchemaVersion(conn);
      +  174  4
                       ensureSchemaVersion(conn);
       175  0
                   } catch (DatabaseException dex) {
       176  0
                       LOGGER.debug("", dex);
       177  0
                       throw new DatabaseException("Database schema does not match this version of dependency-check", dex);
      -  178  2
                   }
      +  178  4
                   }
       179  
               } finally {
      -  180  2
                   if (conn != null) {
      +  180  4
                   if (conn != null) {
       181  
                       try {
      -  182  2
                           conn.close();
      +  182  4
                           conn.close();
       183  0
                       } catch (SQLException ex) {
       184  0
                           LOGGER.debug("An error occurred closing the connection", ex);
      -  185  2
                       }
      +  185  4
                       }
       186  
                   }
       187  
               }
      -  188  2
           }
      +  188  4
           }
       189  
       
       190   @@ -335,24 +335,24 @@
            */
       195  
           public static synchronized void cleanup() {
      -  196  1
               if (driver != null) {
      +  196  2
               if (driver != null) {
       197  
                   try {
      -  198  1
                       DriverManager.deregisterDriver(driver);
      +  198  2
                       DriverManager.deregisterDriver(driver);
       199  0
                   } catch (SQLException ex) {
       200  0
                       LOGGER.debug("An error occurred unloading the database driver", ex);
       201  0
                   } catch (Throwable unexpected) {
       202  0
                       LOGGER.debug(
       203  
                               "An unexpected throwable occurred unloading the database driver", unexpected);
      -  204  1
                   }
      -  205  1
                   driver = null;
      +  204  2
                   }
      +  205  2
                   driver = null;
       206  
               }
      -  207  1
               connectionString = null;
      -  208  1
               userName = null;
      -  209  1
               password = null;
      -  210  1
           }
      +  207  2
               connectionString = null;
      +  208  2
               userName = null;
      +  209  2
               password = null;
      +  210  2
           }
       211  
       
       212   @@ -369,16 +369,16 @@
            */
       218  
           public static Connection getConnection() throws DatabaseException {
      -  219  7
               initialize();
      -  220  7
               Connection conn = null;
      +  219  28
               initialize();
      +  220  28
               Connection conn = null;
       221  
               try {
      -  222  7
                   conn = DriverManager.getConnection(connectionString, userName, password);
      +  222  28
                   conn = DriverManager.getConnection(connectionString, userName, password);
       223  0
               } catch (SQLException ex) {
       224  0
                   LOGGER.debug("", ex);
       225  0
                   throw new DatabaseException("Unable to connect to the database");
      -  226  7
               }
      -  227  7
               return conn;
      +  226  28
               }
      +  227  28
               return conn;
       228  
           }
       229   @@ -397,10 +397,10 @@
            */
       236  
           private static boolean h2DataFileExists() throws IOException {
      -  237  2
               final File dir = Settings.getDataDirectory();
      -  238  2
               final String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME);
      -  239  2
               final File file = new File(dir, fileName);
      -  240  2
               return file.exists();
      +  237  4
               final File dir = Settings.getDataDirectory();
      +  238  4
               final String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME);
      +  239  4
               final File file = new File(dir, fileName);
      +  240  4
               return file.exists();
       241  
           }
       242   @@ -551,7 +551,7 @@
            * Counter to ensure that calls to ensureSchemaVersion does not end up in an endless loop.
       344  
            */
      -  345  1
           private static int callDepth = 0;
      +  345  2
           private static int callDepth = 0;
       346  
       
       347   @@ -568,18 +568,18 @@
            */
       353  
           private static void ensureSchemaVersion(Connection conn) throws DatabaseException {
      -  354  2
               ResultSet rs = null;
      -  355  2
               CallableStatement cs = null;
      +  354  4
               ResultSet rs = null;
      +  355  4
               CallableStatement cs = null;
       356  
               try {
       357  
                   //TODO convert this to use DatabaseProperties
      -  358  2
                   cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'");
      -  359  2
                   rs = cs.executeQuery();
      -  360  2
                   if (rs.next()) {
      -  361  2
                       final DependencyVersion appDbVersion = DependencyVersionUtil.parseVersion(DB_SCHEMA_VERSION);
      -  362  2
                       final DependencyVersion db = DependencyVersionUtil.parseVersion(rs.getString(1));
      -  363  2
                       if (appDbVersion.compareTo(db) > 0) {
      +  358  4
                   cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'");
      +  359  4
                   rs = cs.executeQuery();
      +  360  4
                   if (rs.next()) {
      +  361  4
                       final DependencyVersion appDbVersion = DependencyVersionUtil.parseVersion(DB_SCHEMA_VERSION);
      +  362  4
                       final DependencyVersion db = DependencyVersionUtil.parseVersion(rs.getString(1));
      +  363  4
                       if (appDbVersion.compareTo(db) > 0) {
       364  0
                           LOGGER.debug("Current Schema: {}", DB_SCHEMA_VERSION);
       365  0
                           LOGGER.debug("DB Schema: {}", rs.getString(1));
       366  0
                           updateSchema(conn, appDbVersion, db);
      @@ -589,7 +589,7 @@
                           }
       370  
                       }
      -  371  2
                   } else {
      +  371  4
                   } else {
       372  0
                       throw new DatabaseException("Database schema is missing");
       373  
                   }
      @@ -598,14 +598,14 @@  376  0
                   throw new DatabaseException("Unable to check the database schema version");
       377  
               } finally {
      -  378  2
                   DBUtils.closeResultSet(rs);
      -  379  2
                   DBUtils.closeStatement(cs);
      -  380  2
               }
      -  381  2
           }
      +  378  4
                   DBUtils.closeResultSet(rs);
      +  379  4
                   DBUtils.closeStatement(cs);
      +  380  4
               }
      +  381  4
           }
       382  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CorruptDatabaseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CorruptDatabaseException.html index 5f906a5a7..8fc0c7482 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CorruptDatabaseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CorruptDatabaseException.html @@ -115,6 +115,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CveDB.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CveDB.html index e0217a5c3..4c392cc17 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CveDB.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CveDB.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      CveDB
      47%
      200/420
      57%
      73/128
      5.273
      CveDB
      46%
      201/436
      52%
      73/138
      5.591
       
      @@ -137,7 +137,7 @@
            * The logger.
       60  
            */
      -  61  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class);
      +  61  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class);
       62  
           /**
       63   @@ -152,1045 +152,1139 @@
            * The bundle of statements used when accessing the database.
       68  
            */
      -  69  6
           private ResourceBundle statementBundle = null;
      +  69  26
           private ResourceBundle statementBundle = null;
       70  
       
       71  
           /**
       72   -
            * Creates a new CveDB object and opens the database connection. Note, the connection must be closed by the caller by calling
      +
            * Creates a new CveDB object and opens the database
       73   -
            * the close method.
      +
            * connection. Note, the connection must be closed by the caller by calling
       74   -
            *
      +
            * the close method. ======= Does the underlying connection support batch
       75   -
            * @throws DatabaseException thrown if there is an exception opening the database.
      +
            * operations?
       76  
            */
       77   -
           public CveDB() throws DatabaseException {
      -  78  6
               super();
      +
           private boolean batchSupported;
      +  78   +
       
       79   -
               try {
      -  80  6
                   open();
      +
           /**
      +  80   +
            * Creates a new CveDB object and opens the database connection. Note, the
       81   -
                   try {
      -  82  6
                       final String databaseProductName = conn.getMetaData().getDatabaseProductName();
      -  83  6
                       LOGGER.debug("Database dialect: {}", databaseProductName);
      -  84  6
                       final Locale dbDialect = new Locale(databaseProductName);
      -  85  6
                       statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect);
      -  86  0
                   } catch (SQLException se) {
      -  87  0
                       LOGGER.warn("Problem loading database specific dialect!", se);
      -  88  0
                       statementBundle = ResourceBundle.getBundle("data/dbStatements");
      -  89  6
                   }
      -  90  6
                   databaseProperties = new DatabaseProperties(this);
      -  91  0
               } catch (DatabaseException ex) {
      -  92  0
                   throw ex;
      -  93  6
               }
      -  94  6
           }
      -  95   -
       
      -  96   -
           /**
      -  97   -
            * Returns the database connection.
      -  98   -
            *
      -  99   -
            * @return the database connection
      -  100   +
            * connection must be closed by the caller by calling the close method.
      +  82   +
            * 
      +  83   +
            * @throws DatabaseException thrown if there is an exception opening the
      +  84   +
            * database.
      +  85  
            */
      -  101   -
           protected Connection getConnection() {
      -  102  37
               return conn;
      -  103   -
           }
      -  104   -
       
      +  86   +
           public CveDB() throws DatabaseException {
      +  87  26
               super();
      +  88   +
               try {
      +  89  26
                   open();
      +  90   +
                   try {
      +  91  26
                       final String databaseProductName = conn.getMetaData().getDatabaseProductName();
      +  92  26
                       batchSupported = conn.getMetaData().supportsBatchUpdates();
      +  93  26
                       LOGGER.debug("Database dialect: {}", databaseProductName);
      +  94  26
                       final Locale dbDialect = new Locale(databaseProductName);
      +  95  26
                       statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect);
      +  96  0
                   } catch (SQLException se) {
      +  97  0
                       LOGGER.warn("Problem loading database specific dialect!", se);
      +  98  0
                       statementBundle = ResourceBundle.getBundle("data/dbStatements");
      +  99  26
                   }
      +  100  26
                   databaseProperties = new DatabaseProperties(this);
      +  101  0
               } catch (DatabaseException ex) {
      +  102  0
                   throw ex;
      +  103  26
               }
      +  104  26
           }
       105   -
           /**
      +
       
       106   -
            * Opens the database connection. If the database does not exist, it will create a new one.
      +
           /**
       107   -
            *
      +
            * Returns the database connection.
       108   -
            * @throws DatabaseException thrown if there is an error opening the database connection
      +
            *
       109   -
            */
      +
            * @return the database connection
       110   -
           public final void open() throws DatabaseException {
      -  111  12
               if (!isOpen()) {
      -  112  6
                   conn = ConnectionFactory.getConnection();
      +
            */
      +  111   +
           protected Connection getConnection() {
      +  112  90
               return conn;
       113   -
               }
      -  114  12
           }
      +
           }
      +  114   +
       
       115   -
       
      +
           /**
       116   -
           /**
      +
            * Opens the database connection. If the database does not exist, it will
       117   -
            * Closes the DB4O database. Close should be called on this object when it is done being used.
      +
            * create a new one.
       118   -
            */
      +
            *
       119   -
           public void close() {
      -  120  8
               if (conn != null) {
      +
            * @throws DatabaseException thrown if there is an error opening the
      +  120   +
            * database connection
       121   -
                   try {
      -  122  6
                       conn.close();
      -  123  0
                   } catch (SQLException ex) {
      -  124  0
                       LOGGER.error("There was an error attempting to close the CveDB, see the log for more details.");
      -  125  0
                       LOGGER.debug("", ex);
      -  126  0
                   } catch (Throwable ex) {
      -  127  0
                       LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details.");
      -  128  0
                       LOGGER.debug("", ex);
      -  129  6
                   }
      -  130  6
                   conn = null;
      -  131   +
            */
      +  122   +
           public final void open() throws DatabaseException {
      +  123  52
               if (!isOpen()) {
      +  124  26
                   conn = ConnectionFactory.getConnection();
      +  125  
               }
      -  132  8
           }
      -  133   +  126  52
           }
      +  127  
       
      +  128   +
           /**
      +  129   +
            * Closes the DB4O database. Close should be called on this object when it
      +  130   +
            * is done being used.
      +  131   +
            */
      +  132   +
           public void close() {
      +  133  49
               if (conn != null) {
       134   -
           /**
      -  135   -
            * Returns whether the database connection is open or closed.
      -  136   -
            *
      -  137   -
            * @return whether the database connection is open or closed
      -  138   -
            */
      -  139   -
           public boolean isOpen() {
      -  140  12
               return conn != null;
      -  141   -
           }
      -  142   -
       
      -  143   -
           /**
      -  144   -
            * Commits all completed transactions.
      -  145   -
            *
      -  146   -
            * @throws SQLException thrown if a SQL Exception occurs
      -  147   -
            */
      -  148   -
           public void commit() throws SQLException {
      -  149   -
               //temporary remove this as autocommit is on.
      -  150   -
               //if (conn != null) {
      -  151   -
               //    conn.commit();
      -  152   -
               //}
      -  153  0
           }
      -  154   -
       
      -  155   -
           /**
      -  156   -
            * Cleans up the object and ensures that "close" has been called.
      -  157   -
            *
      -  158   -
            * @throws Throwable thrown if there is a problem
      -  159   -
            */
      -  160   -
           @Override
      -  161   -
           @SuppressWarnings("FinalizeDeclaration")
      -  162   -
           protected void finalize() throws Throwable {
      -  163  2
               LOGGER.debug("Entering finalize");
      -  164  2
               close();
      -  165  2
               super.finalize();
      -  166  2
           }
      -  167   -
           /**
      -  168   -
            * Database properties object containing the 'properties' from the database table.
      -  169   -
            */
      -  170   -
           private DatabaseProperties databaseProperties;
      -  171   -
       
      -  172   -
           /**
      -  173   -
            * Get the value of databaseProperties.
      -  174   -
            *
      -  175   -
            * @return the value of databaseProperties
      -  176   -
            */
      -  177   -
           public DatabaseProperties getDatabaseProperties() {
      -  178  3
               return databaseProperties;
      -  179   -
           }
      -  180   -
       
      -  181   -
           /**
      -  182   -
            * Searches the CPE entries in the database and retrieves all entries for a given vendor and product combination. The returned
      -  183   -
            * list will include all versions of the product that are registered in the NVD CVE data.
      -  184   -
            *
      -  185   -
            * @param vendor the identified vendor name of the dependency being analyzed
      -  186   -
            * @param product the identified name of the product of the dependency being analyzed
      -  187   -
            * @return a set of vulnerable software
      -  188   -
            */
      -  189   -
           public Set<VulnerableSoftware> getCPEs(String vendor, String product) {
      -  190  3
               final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>();
      -  191  3
               ResultSet rs = null;
      -  192  3
               PreparedStatement ps = null;
      -  193   -
               try {
      -  194  3
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES"));
      -  195  3
                   ps.setString(1, vendor);
      -  196  3
                   ps.setString(2, product);
      -  197  3
                   rs = ps.executeQuery();
      -  198   -
       
      -  199  112
                   while (rs.next()) {
      -  200  109
                       final VulnerableSoftware vs = new VulnerableSoftware();
      -  201  109
                       vs.setCpe(rs.getString(1));
      -  202  109
                       cpe.add(vs);
      -  203  109
                   }
      -  204  0
               } catch (SQLException ex) {
      -  205  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      -  206  0
                   LOGGER.debug("", ex);
      -  207   -
               } finally {
      -  208  3
                   DBUtils.closeResultSet(rs);
      -  209  3
                   DBUtils.closeStatement(ps);
      -  210  3
               }
      -  211  3
               return cpe;
      -  212   -
           }
      -  213   -
       
      -  214   -
           /**
      -  215   -
            * Returns the entire list of vendor/product combinations.
      -  216   -
            *
      -  217   -
            * @return the entire list of vendor/product combinations
      -  218   -
            * @throws DatabaseException thrown when there is an error retrieving the data from the DB
      -  219   -
            */
      -  220   -
           public Set<Pair<String, String>> getVendorProductList() throws DatabaseException {
      -  221  1
               final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>();
      -  222  1
               ResultSet rs = null;
      -  223  1
               PreparedStatement ps = null;
      -  224   -
               try {
      -  225  1
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST"));
      -  226  1
                   rs = ps.executeQuery();
      -  227  25716
                   while (rs.next()) {
      -  228  25715
                       data.add(new Pair<String, String>(rs.getString(1), rs.getString(2)));
      -  229   -
                   }
      -  230  0
               } catch (SQLException ex) {
      -  231  0
                   final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
      -  232  0
                   throw new DatabaseException(msg, ex);
      -  233   -
               } finally {
      -  234  1
                   DBUtils.closeResultSet(rs);
      -  235  1
                   DBUtils.closeStatement(ps);
      -  236  1
               }
      -  237  1
               return data;
      -  238   -
           }
      -  239   -
       
      -  240   -
           /**
      -  241   -
            * Returns a set of properties.
      -  242   -
            *
      -  243   -
            * @return the properties from the database
      -  244   -
            */
      -  245   -
           Properties getProperties() {
      -  246  6
               final Properties prop = new Properties();
      -  247  6
               PreparedStatement ps = null;
      -  248  6
               ResultSet rs = null;
      -  249   -
               try {
      -  250  6
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES"));
      -  251  6
                   rs = ps.executeQuery();
      -  252  120
                   while (rs.next()) {
      -  253  114
                       prop.setProperty(rs.getString(1), rs.getString(2));
      -  254   -
                   }
      -  255  0
               } catch (SQLException ex) {
      -  256  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      -  257  0
                   LOGGER.debug("", ex);
      -  258   -
               } finally {
      -  259  6
                   DBUtils.closeStatement(ps);
      -  260  6
                   DBUtils.closeResultSet(rs);
      -  261  6
               }
      -  262  6
               return prop;
      -  263   -
           }
      -  264   -
       
      -  265   -
           /**
      -  266   -
            * Saves a property to the database.
      -  267   -
            *
      -  268   -
            * @param key the property key
      -  269   -
            * @param value the property value
      -  270   -
            */
      -  271   -
           void saveProperty(String key, String value) {
      -  272   -
               try {
      -  273  
                   try {
      -  274  0
                       final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY"));
      +  135  26
                       conn.close();
      +  136  0
                   } catch (SQLException ex) {
      +  137  0
                       LOGGER.error("There was an error attempting to close the CveDB, see the log for more details.");
      +  138  0
                       LOGGER.debug("", ex);
      +  139  0
                   } catch (Throwable ex) {
      +  140  0
                       LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details.");
      +  141  0
                       LOGGER.debug("", ex);
      +  142  26
                   }
      +  143  26
                   conn = null;
      +  144   +
               }
      +  145  49
           }
      +  146   +
       
      +  147   +
           /**
      +  148   +
            * Returns whether the database connection is open or closed.
      +  149   +
            *
      +  150   +
            * @return whether the database connection is open or closed
      +  151   +
            */
      +  152   +
           public boolean isOpen() {
      +  153  52
               return conn != null;
      +  154   +
           }
      +  155   +
       
      +  156   +
           /**
      +  157   +
            * Commits all completed transactions.
      +  158   +
            *
      +  159   +
            * @throws SQLException thrown if a SQL Exception occurs
      +  160   +
            */
      +  161   +
           public void commit() throws SQLException {
      +  162   +
               //temporary remove this as autocommit is on.
      +  163   +
               //if (conn != null) {
      +  164   +
               //    conn.commit();
      +  165   +
               //}
      +  166  0
           }
      +  167   +
       
      +  168   +
           /**
      +  169   +
            * Cleans up the object and ensures that "close" has been called.
      +  170   +
            *
      +  171   +
            * @throws Throwable thrown if there is a problem
      +  172   +
            */
      +  173   +
           @Override
      +  174   +
           @SuppressWarnings("FinalizeDeclaration")
      +  175   +
           protected void finalize() throws Throwable {
      +  176  23
               LOGGER.debug("Entering finalize");
      +  177  23
               close();
      +  178  23
               super.finalize();
      +  179  23
           }
      +  180   +
           /**
      +  181   +
            * Database properties object containing the 'properties' from the database
      +  182   +
            * table.
      +  183   +
            */
      +  184   +
           private DatabaseProperties databaseProperties;
      +  185   +
       
      +  186   +
           /**
      +  187   +
            * Get the value of databaseProperties.
      +  188   +
            *
      +  189   +
            * @return the value of databaseProperties
      +  190   +
            */
      +  191   +
           public DatabaseProperties getDatabaseProperties() {
      +  192  6
               return databaseProperties;
      +  193   +
           }
      +  194   +
       
      +  195   +
           /**
      +  196   +
            * Searches the CPE entries in the database and retrieves all entries for a
      +  197   +
            * given vendor and product combination. The returned list will include all
      +  198   +
            * versions of the product that are registered in the NVD CVE data.
      +  199   +
            *
      +  200   +
            * @param vendor the identified vendor name of the dependency being analyzed
      +  201   +
            * @param product the identified name of the product of the dependency being
      +  202   +
            * analyzed
      +  203   +
            * @return a set of vulnerable software
      +  204   +
            */
      +  205   +
           public Set<VulnerableSoftware> getCPEs(String vendor, String product) {
      +  206  6
               final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>();
      +  207  6
               ResultSet rs = null;
      +  208  6
               PreparedStatement ps = null;
      +  209   +
               try {
      +  210  6
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES"));
      +  211  6
                   ps.setString(1, vendor);
      +  212  6
                   ps.setString(2, product);
      +  213  6
                   rs = ps.executeQuery();
      +  214   +
       
      +  215  224
                   while (rs.next()) {
      +  216  218
                       final VulnerableSoftware vs = new VulnerableSoftware();
      +  217  218
                       vs.setCpe(rs.getString(1));
      +  218  218
                       cpe.add(vs);
      +  219  218
                   }
      +  220  0
               } catch (SQLException ex) {
      +  221  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      +  222  0
                   LOGGER.debug("", ex);
      +  223   +
               } finally {
      +  224  6
                   DBUtils.closeResultSet(rs);
      +  225  6
                   DBUtils.closeStatement(ps);
      +  226  6
               }
      +  227  6
               return cpe;
      +  228   +
           }
      +  229   +
       
      +  230   +
           /**
      +  231   +
            * Returns the entire list of vendor/product combinations.
      +  232   +
            *
      +  233   +
            * @return the entire list of vendor/product combinations
      +  234   +
            * @throws DatabaseException thrown when there is an error retrieving the
      +  235   +
            * data from the DB
      +  236   +
            */
      +  237   +
           public Set<Pair<String, String>> getVendorProductList() throws DatabaseException {
      +  238  4
               final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>();
      +  239  4
               ResultSet rs = null;
      +  240  4
               PreparedStatement ps = null;
      +  241   +
               try {
      +  242  4
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST"));
      +  243  4
                   rs = ps.executeQuery();
      +  244  103672
                   while (rs.next()) {
      +  245  103668
                       data.add(new Pair<String, String>(rs.getString(1), rs.getString(2)));
      +  246   +
                   }
      +  247  0
               } catch (SQLException ex) {
      +  248  0
                   final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
      +  249  0
                   throw new DatabaseException(msg, ex);
      +  250   +
               } finally {
      +  251  4
                   DBUtils.closeResultSet(rs);
      +  252  4
                   DBUtils.closeStatement(ps);
      +  253  4
               }
      +  254  4
               return data;
      +  255   +
           }
      +  256   +
       
      +  257   +
           /**
      +  258   +
            * Returns a set of properties.
      +  259   +
            *
      +  260   +
            * @return the properties from the database
      +  261   +
            */
      +  262   +
           Properties getProperties() {
      +  263  26
               final Properties prop = new Properties();
      +  264  26
               PreparedStatement ps = null;
      +  265  26
               ResultSet rs = null;
      +  266   +
               try {
      +  267  26
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES"));
      +  268  26
                   rs = ps.executeQuery();
      +  269  546
                   while (rs.next()) {
      +  270  520
                       prop.setProperty(rs.getString(1), rs.getString(2));
      +  271   +
                   }
      +  272  0
               } catch (SQLException ex) {
      +  273  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      +  274  0
                   LOGGER.debug("", ex);
       275   -
                       try {
      -  276  0
                           mergeProperty.setString(1, key);
      -  277  0
                           mergeProperty.setString(2, value);
      -  278  0
                           mergeProperty.executeUpdate();
      -  279   -
                       } finally {
      -  280  0
                           DBUtils.closeStatement(mergeProperty);
      -  281  0
                       }
      -  282  0
                   } catch (MissingResourceException mre) {
      +
               } finally {
      +  276  26
                   DBUtils.closeStatement(ps);
      +  277  26
                   DBUtils.closeResultSet(rs);
      +  278  26
               }
      +  279  26
               return prop;
      +  280   +
           }
      +  281   +
       
      +  282   +
           /**
       283   -
                       // No Merge statement, so doing an Update/Insert...
      -  284  0
                       PreparedStatement updateProperty = null;
      -  285  0
                       PreparedStatement insertProperty = null;
      +
            * Saves a property to the database.
      +  284   +
            *
      +  285   +
            * @param key the property key
       286   +
            * @param value the property value
      +  287   +
            */
      +  288   +
           void saveProperty(String key, String value) {
      +  289   +
               try {
      +  290   +
                   try {
      +  291  0
                       final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY"));
      +  292  
                       try {
      -  287  0
                           updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
      -  288  0
                           updateProperty.setString(1, value);
      -  289  0
                           updateProperty.setString(2, key);
      -  290  0
                           if (updateProperty.executeUpdate() == 0) {
      -  291  0
                               insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
      -  292  0
                               insertProperty.setString(1, key);
      -  293  0
                               insertProperty.setString(2, value);
      -  294  0
                               insertProperty.executeUpdate();
      -  295   -
                           }
      +  293  0
                           mergeProperty.setString(1, key);
      +  294  0
                           mergeProperty.setString(2, value);
      +  295  0
                           mergeProperty.executeUpdate();
       296  
                       } finally {
      -  297  0
                           DBUtils.closeStatement(updateProperty);
      -  298  0
                           DBUtils.closeStatement(insertProperty);
      -  299  0
                       }
      -  300  0
                   }
      -  301  0
               } catch (SQLException ex) {
      -  302  0
                   LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
      -  303  0
                   LOGGER.debug("", ex);
      -  304  0
               }
      -  305  0
           }
      -  306   -
       
      -  307   -
           /**
      -  308   -
            * Retrieves the vulnerabilities associated with the specified CPE.
      -  309   -
            *
      -  310   -
            * @param cpeStr the CPE name
      -  311   -
            * @return a list of Vulnerabilities
      +  297  0
                           DBUtils.closeStatement(mergeProperty);
      +  298  0
                       }
      +  299  0
                   } catch (MissingResourceException mre) {
      +  300   +
                       // No Merge statement, so doing an Update/Insert...
      +  301  0
                       PreparedStatement updateProperty = null;
      +  302  0
                       PreparedStatement insertProperty = null;
      +  303   +
                       try {
      +  304  0
                           updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
      +  305  0
                           updateProperty.setString(1, value);
      +  306  0
                           updateProperty.setString(2, key);
      +  307  0
                           if (updateProperty.executeUpdate() == 0) {
      +  308  0
                               insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
      +  309  0
                               insertProperty.setString(1, key);
      +  310  0
                               insertProperty.setString(2, value);
      +  311  0
                               insertProperty.executeUpdate();
       312   -
            * @throws DatabaseException thrown if there is an exception retrieving data
      +
                           }
       313   -
            */
      -  314   -
           public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException {
      -  315  3
               final VulnerableSoftware cpe = new VulnerableSoftware();
      -  316   -
               try {
      -  317  3
                   cpe.parseName(cpeStr);
      -  318  0
               } catch (UnsupportedEncodingException ex) {
      -  319  0
                   LOGGER.trace("", ex);
      -  320  3
               }
      -  321  3
               final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
      -  322  3
               final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
      +
                       } finally {
      +  314  0
                           DBUtils.closeStatement(updateProperty);
      +  315  0
                           DBUtils.closeStatement(insertProperty);
      +  316  0
                       }
      +  317  0
                   }
      +  318  0
               } catch (SQLException ex) {
      +  319  0
                   LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
      +  320  0
                   LOGGER.debug("", ex);
      +  321  0
               }
      +  322  0
           }
       323  
       
      -  324  3
               PreparedStatement ps = null;
      -  325  3
               ResultSet rs = null;
      +  324   +
           /**
      +  325   +
            * Retrieves the vulnerabilities associated with the specified CPE.
       326   +
            *
      +  327   +
            * @param cpeStr the CPE name
      +  328   +
            * @return a list of Vulnerabilities
      +  329   +
            * @throws DatabaseException thrown if there is an exception retrieving data
      +  330   +
            */
      +  331   +
           public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException {
      +  332  6
               final VulnerableSoftware cpe = new VulnerableSoftware();
      +  333  
               try {
      -  327  3
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE"));
      -  328  3
                   ps.setString(1, cpe.getVendor());
      -  329  3
                   ps.setString(2, cpe.getProduct());
      -  330  3
                   rs = ps.executeQuery();
      -  331  3
                   String currentCVE = "";
      -  332   +  334  6
                   cpe.parseName(cpeStr);
      +  335  0
               } catch (UnsupportedEncodingException ex) {
      +  336  0
                   LOGGER.trace("", ex);
      +  337  6
               }
      +  338  6
               final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
      +  339  6
               final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
      +  340  
       
      -  333  3
                   final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>();
      -  334  282
                   while (rs.next()) {
      -  335  279
                       final String cveId = rs.getString(1);
      -  336  279
                       if (!currentCVE.equals(cveId)) { //check for match and add
      -  337  10
                           final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
      -  338  10
                           if (matchedCPE != null) {
      -  339  6
                               final Vulnerability v = getVulnerability(currentCVE);
      -  340  6
                               v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
      -  341  6
                               vulnerabilities.add(v);
      -  342   +  341  6
               PreparedStatement ps = null;
      +  342  6
               ResultSet rs = null;
      +  343   +
               try {
      +  344  6
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE"));
      +  345  6
                   ps.setString(1, cpe.getVendor());
      +  346  6
                   ps.setString(2, cpe.getProduct());
      +  347  6
                   rs = ps.executeQuery();
      +  348  6
                   String currentCVE = "";
      +  349   +
       
      +  350  6
                   final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>();
      +  351  564
                   while (rs.next()) {
      +  352  558
                       final String cveId = rs.getString(1);
      +  353  558
                       if (!currentCVE.equals(cveId)) { //check for match and add
      +  354  20
                           final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
      +  355  20
                           if (matchedCPE != null) {
      +  356  12
                               final Vulnerability v = getVulnerability(currentCVE);
      +  357  12
                               v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
      +  358  12
                               vulnerabilities.add(v);
      +  359  
                           }
      -  343  10
                           vulnSoftware.clear();
      -  344  10
                           currentCVE = cveId;
      -  345   +  360  20
                           vulnSoftware.clear();
      +  361  20
                           currentCVE = cveId;
      +  362  
                       }
      -  346   +  363  
       
      -  347  279
                       final String cpeId = rs.getString(2);
      -  348  279
                       final String previous = rs.getString(3);
      -  349  279
                       final Boolean p = previous != null && !previous.isEmpty();
      -  350  279
                       vulnSoftware.put(cpeId, p);
      -  351  279
                   }
      -  352   -
                   //remember to process the last set of CVE/CPE entries
      -  353  3
                   final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
      -  354  3
                   if (matchedCPE != null) {
      -  355  2
                       final Vulnerability v = getVulnerability(currentCVE);
      -  356  2
                       v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
      -  357  2
                       vulnerabilities.add(v);
      -  358   -
                   }
      -  359  0
               } catch (SQLException ex) {
      -  360  0
                   throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
      -  361   -
               } finally {
      -  362  3
                   DBUtils.closeResultSet(rs);
      -  363  3
                   DBUtils.closeStatement(ps);
      -  364  3
               }
      -  365  3
               return vulnerabilities;
      -  366   -
           }
      -  367   -
       
      -  368   -
           /**
      +  364  558
                       final String cpeId = rs.getString(2);
      +  365  558
                       final String previous = rs.getString(3);
      +  366  558
                       final Boolean p = previous != null && !previous.isEmpty();
      +  367  558
                       vulnSoftware.put(cpeId, p);
      +  368  558
                   }
       369   -
            * Gets a vulnerability for the provided CVE.
      -  370   -
            *
      -  371   -
            * @param cve the CVE to lookup
      -  372   -
            * @return a vulnerability object
      -  373   -
            * @throws DatabaseException if an exception occurs
      -  374   -
            */
      +
                   //remember to process the last set of CVE/CPE entries
      +  370  6
                   final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
      +  371  6
                   if (matchedCPE != null) {
      +  372  4
                       final Vulnerability v = getVulnerability(currentCVE);
      +  373  4
                       v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
      +  374  4
                       vulnerabilities.add(v);
       375   -
           private Vulnerability getVulnerability(String cve) throws DatabaseException {
      -  376  8
               PreparedStatement psV = null;
      -  377  8
               PreparedStatement psR = null;
      -  378  8
               PreparedStatement psS = null;
      -  379  8
               ResultSet rsV = null;
      -  380  8
               ResultSet rsR = null;
      -  381  8
               ResultSet rsS = null;
      -  382  8
               Vulnerability vuln = null;
      -  383   -
               try {
      -  384  8
                   psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY"));
      -  385  8
                   psV.setString(1, cve);
      -  386  8
                   rsV = psV.executeQuery();
      -  387  8
                   if (rsV.next()) {
      -  388  8
                       vuln = new Vulnerability();
      -  389  8
                       vuln.setName(cve);
      -  390  8
                       vuln.setDescription(rsV.getString(2));
      -  391  8
                       String cwe = rsV.getString(3);
      -  392  8
                       if (cwe != null) {
      -  393  8
                           final String name = CweDB.getCweName(cwe);
      -  394  8
                           if (name != null) {
      -  395  7
                               cwe += ' ' + name;
      -  396   -
                           }
      -  397   -
                       }
      -  398  8
                       final int cveId = rsV.getInt(1);
      -  399  8
                       vuln.setCwe(cwe);
      -  400  8
                       vuln.setCvssScore(rsV.getFloat(4));
      -  401  8
                       vuln.setCvssAccessVector(rsV.getString(5));
      -  402  8
                       vuln.setCvssAccessComplexity(rsV.getString(6));
      -  403  8
                       vuln.setCvssAuthentication(rsV.getString(7));
      -  404  8
                       vuln.setCvssConfidentialityImpact(rsV.getString(8));
      -  405  8
                       vuln.setCvssIntegrityImpact(rsV.getString(9));
      -  406  8
                       vuln.setCvssAvailabilityImpact(rsV.getString(10));
      -  407   -
       
      -  408  8
                       psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES"));
      -  409  8
                       psR.setInt(1, cveId);
      -  410  8
                       rsR = psR.executeQuery();
      -  411  74
                       while (rsR.next()) {
      -  412  66
                           vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3));
      -  413   -
                       }
      -  414  8
                       psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE"));
      -  415  8
                       psS.setInt(1, cveId);
      -  416  8
                       rsS = psS.executeQuery();
      -  417  247
                       while (rsS.next()) {
      -  418  239
                           final String cpe = rsS.getString(1);
      -  419  239
                           final String prevVersion = rsS.getString(2);
      -  420  239
                           if (prevVersion == null) {
      -  421  231
                               vuln.addVulnerableSoftware(cpe);
      -  422   -
                           } else {
      -  423  8
                               vuln.addVulnerableSoftware(cpe, prevVersion);
      -  424   -
                           }
      -  425  239
                       }
      -  426  
                   }
      -  427  0
               } catch (SQLException ex) {
      -  428  0
                   throw new DatabaseException("Error retrieving " + cve, ex);
      -  429   +  376  0
               } catch (SQLException ex) {
      +  377  0
                   throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
      +  378  
               } finally {
      -  430  8
                   DBUtils.closeResultSet(rsV);
      -  431  8
                   DBUtils.closeResultSet(rsR);
      -  432  8
                   DBUtils.closeResultSet(rsS);
      -  433  8
                   DBUtils.closeStatement(psV);
      -  434  8
                   DBUtils.closeStatement(psR);
      -  435  8
                   DBUtils.closeStatement(psS);
      -  436  8
               }
      -  437  8
               return vuln;
      -  438   +  379  6
                   DBUtils.closeResultSet(rs);
      +  380  6
                   DBUtils.closeStatement(ps);
      +  381  6
               }
      +  382  6
               return vulnerabilities;
      +  383  
           }
      -  439   +  384  
       
      -  440   +  385  
           /**
      -  441   -
            * Updates the vulnerability within the database. If the vulnerability does not exist it will be added.
      -  442   +  386   +
            * Gets a vulnerability for the provided CVE.
      +  387  
            *
      -  443   -
            * @param vuln the vulnerability to add to the database
      -  444   -
            * @throws DatabaseException is thrown if the database
      -  445   +  388   +
            * @param cve the CVE to lookup
      +  389   +
            * @return a vulnerability object
      +  390   +
            * @throws DatabaseException if an exception occurs
      +  391  
            */
      -  446   -
           public void updateVulnerability(Vulnerability vuln) throws DatabaseException {
      -  447  0
               PreparedStatement selectVulnerabilityId = null;
      -  448  0
               PreparedStatement deleteVulnerability = null;
      -  449  0
               PreparedStatement deleteReferences = null;
      -  450  0
               PreparedStatement deleteSoftware = null;
      -  451  0
               PreparedStatement updateVulnerability = null;
      -  452  0
               PreparedStatement insertVulnerability = null;
      -  453  0
               PreparedStatement insertReference = null;
      -  454  0
               PreparedStatement selectCpeId = null;
      -  455  0
               PreparedStatement insertCpe = null;
      -  456  0
               PreparedStatement insertSoftware = null;
      +  392   +
           public Vulnerability getVulnerability(String cve) throws DatabaseException {
      +  393  16
               PreparedStatement psV = null;
      +  394  16
               PreparedStatement psR = null;
      +  395  16
               PreparedStatement psS = null;
      +  396  16
               ResultSet rsV = null;
      +  397  16
               ResultSet rsR = null;
      +  398  16
               ResultSet rsS = null;
      +  399  16
               Vulnerability vuln = null;
      +  400   +
       
      +  401   +
               try {
      +  402  16
                   psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY"));
      +  403  16
                   psV.setString(1, cve);
      +  404  16
                   rsV = psV.executeQuery();
      +  405  16
                   if (rsV.next()) {
      +  406  16
                       vuln = new Vulnerability();
      +  407  16
                       vuln.setName(cve);
      +  408  16
                       vuln.setDescription(rsV.getString(2));
      +  409  16
                       String cwe = rsV.getString(3);
      +  410  16
                       if (cwe != null) {
      +  411  16
                           final String name = CweDB.getCweName(cwe);
      +  412  16
                           if (name != null) {
      +  413  14
                               cwe += ' ' + name;
      +  414   +
                           }
      +  415   +
                       }
      +  416  16
                       final int cveId = rsV.getInt(1);
      +  417  16
                       vuln.setCwe(cwe);
      +  418  16
                       vuln.setCvssScore(rsV.getFloat(4));
      +  419  16
                       vuln.setCvssAccessVector(rsV.getString(5));
      +  420  16
                       vuln.setCvssAccessComplexity(rsV.getString(6));
      +  421  16
                       vuln.setCvssAuthentication(rsV.getString(7));
      +  422  16
                       vuln.setCvssConfidentialityImpact(rsV.getString(8));
      +  423  16
                       vuln.setCvssIntegrityImpact(rsV.getString(9));
      +  424  16
                       vuln.setCvssAvailabilityImpact(rsV.getString(10));
      +  425   +
       
      +  426  16
                       psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES"));
      +  427  16
                       psR.setInt(1, cveId);
      +  428  16
                       rsR = psR.executeQuery();
      +  429  152
                       while (rsR.next()) {
      +  430  136
                           vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3));
      +  431   +
                       }
      +  432  16
                       psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE"));
      +  433  16
                       psS.setInt(1, cveId);
      +  434  16
                       rsS = psS.executeQuery();
      +  435  488
                       while (rsS.next()) {
      +  436  472
                           final String cpe = rsS.getString(1);
      +  437  472
                           final String prevVersion = rsS.getString(2);
      +  438  472
                           if (prevVersion == null) {
      +  439  456
                               vuln.addVulnerableSoftware(cpe);
      +  440   +
                           } else {
      +  441  16
                               vuln.addVulnerableSoftware(cpe, prevVersion);
      +  442   +
                           }
      +  443  472
                       }
      +  444   +
                   }
      +  445  0
               } catch (SQLException ex) {
      +  446  0
                   throw new DatabaseException("Error retrieving " + cve, ex);
      +  447   +
               } finally {
      +  448  16
                   DBUtils.closeResultSet(rsV);
      +  449  16
                   DBUtils.closeResultSet(rsR);
      +  450  16
                   DBUtils.closeResultSet(rsS);
      +  451  16
                   DBUtils.closeStatement(psV);
      +  452  16
                   DBUtils.closeStatement(psR);
      +  453  16
                   DBUtils.closeStatement(psS);
      +  454  16
               }
      +  455  16
               return vuln;
      +  456   +
           }
       457  
       
       458   -
               try {
      -  459  0
                   selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID"));
      -  460  0
                   deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY"));
      -  461  0
                   deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE"));
      -  462  0
                   deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE"));
      -  463  0
                   updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY"));
      -  464  0
                   final String[] ids = {"id"};
      -  465  0
                   insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"),
      -  466   -
                           //Statement.RETURN_GENERATED_KEYS);
      -  467   -
                           ids);
      -  468  0
                   insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE"));
      -  469  0
                   selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID"));
      -  470  0
                   insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"),
      -  471   -
                           //Statement.RETURN_GENERATED_KEYS);
      -  472   -
                           ids);
      -  473  0
                   insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE"));
      -  474  0
                   int vulnerabilityId = 0;
      -  475  0
                   selectVulnerabilityId.setString(1, vuln.getName());
      -  476  0
                   ResultSet rs = selectVulnerabilityId.executeQuery();
      -  477  0
                   if (rs.next()) {
      -  478  0
                       vulnerabilityId = rs.getInt(1);
      -  479   -
                       // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier.
      -  480  0
                       deleteReferences.setInt(1, vulnerabilityId);
      -  481  0
                       deleteReferences.execute();
      -  482  0
                       deleteSoftware.setInt(1, vulnerabilityId);
      -  483  0
                       deleteSoftware.execute();
      -  484   -
                   }
      -  485  0
                   DBUtils.closeResultSet(rs);
      -  486  0
                   rs = null;
      -  487  0
                   if (vulnerabilityId != 0) {
      -  488  0
                       if (vuln.getDescription().contains("** REJECT **")) {
      -  489  0
                           deleteVulnerability.setInt(1, vulnerabilityId);
      -  490  0
                           deleteVulnerability.executeUpdate();
      -  491   -
                       } else {
      -  492  0
                           updateVulnerability.setString(1, vuln.getDescription());
      -  493  0
                           updateVulnerability.setString(2, vuln.getCwe());
      -  494  0
                           updateVulnerability.setFloat(3, vuln.getCvssScore());
      -  495  0
                           updateVulnerability.setString(4, vuln.getCvssAccessVector());
      -  496  0
                           updateVulnerability.setString(5, vuln.getCvssAccessComplexity());
      -  497  0
                           updateVulnerability.setString(6, vuln.getCvssAuthentication());
      -  498  0
                           updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact());
      -  499  0
                           updateVulnerability.setString(8, vuln.getCvssIntegrityImpact());
      -  500  0
                           updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact());
      -  501  0
                           updateVulnerability.setInt(10, vulnerabilityId);
      -  502  0
                           updateVulnerability.executeUpdate();
      -  503   -
                       }
      -  504   -
                   } else {
      -  505  0
                       insertVulnerability.setString(1, vuln.getName());
      -  506  0
                       insertVulnerability.setString(2, vuln.getDescription());
      -  507  0
                       insertVulnerability.setString(3, vuln.getCwe());
      -  508  0
                       insertVulnerability.setFloat(4, vuln.getCvssScore());
      -  509  0
                       insertVulnerability.setString(5, vuln.getCvssAccessVector());
      -  510  0
                       insertVulnerability.setString(6, vuln.getCvssAccessComplexity());
      -  511  0
                       insertVulnerability.setString(7, vuln.getCvssAuthentication());
      -  512  0
                       insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact());
      -  513  0
                       insertVulnerability.setString(9, vuln.getCvssIntegrityImpact());
      -  514  0
                       insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact());
      -  515  0
                       insertVulnerability.execute();
      -  516   -
                       try {
      -  517  0
                           rs = insertVulnerability.getGeneratedKeys();
      -  518  0
                           rs.next();
      -  519  0
                           vulnerabilityId = rs.getInt(1);
      -  520  0
                       } catch (SQLException ex) {
      -  521  0
                           final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName());
      -  522  0
                           throw new DatabaseException(msg, ex);
      -  523   -
                       } finally {
      -  524  0
                           DBUtils.closeResultSet(rs);
      -  525  0
                           rs = null;
      -  526  0
                       }
      -  527   -
                   }
      -  528  0
                   insertReference.setInt(1, vulnerabilityId);
      -  529  0
                   for (Reference r : vuln.getReferences()) {
      -  530  0
                       insertReference.setString(2, r.getName());
      -  531  0
                       insertReference.setString(3, r.getUrl());
      -  532  0
                       insertReference.setString(4, r.getSource());
      -  533  0
                       insertReference.execute();
      -  534  0
                   }
      -  535  0
                   for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
      -  536  0
                       int cpeProductId = 0;
      -  537  0
                       selectCpeId.setString(1, s.getName());
      -  538   -
                       try {
      -  539  0
                           rs = selectCpeId.executeQuery();
      -  540  0
                           if (rs.next()) {
      -  541  0
                               cpeProductId = rs.getInt(1);
      -  542   -
                           }
      -  543  0
                       } catch (SQLException ex) {
      -  544  0
                           throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex);
      -  545   -
                       } finally {
      -  546  0
                           DBUtils.closeResultSet(rs);
      -  547  0
                           rs = null;
      -  548  0
                       }
      -  549   +
           /**
      +  459   +
            * Updates the vulnerability within the database. If the vulnerability does
      +  460   +
            * not exist it will be added.
      +  461   +
            *
      +  462   +
            * @param vuln the vulnerability to add to the database
      +  463   +
            * @throws DatabaseException is thrown if the database
      +  464   +
            */
      +  465   +
           public void updateVulnerability(Vulnerability vuln) throws DatabaseException {
      +  466  0
               PreparedStatement selectVulnerabilityId = null;
      +  467  0
               PreparedStatement deleteVulnerability = null;
      +  468  0
               PreparedStatement deleteReferences = null;
      +  469  0
               PreparedStatement deleteSoftware = null;
      +  470  0
               PreparedStatement updateVulnerability = null;
      +  471  0
               PreparedStatement insertVulnerability = null;
      +  472  0
               PreparedStatement insertReference = null;
      +  473  0
               PreparedStatement selectCpeId = null;
      +  474  0
               PreparedStatement insertCpe = null;
      +  475  0
               PreparedStatement insertSoftware = null;
      +  476  
       
      -  550  0
                       if (cpeProductId == 0) {
      -  551  0
                           insertCpe.setString(1, s.getName());
      -  552  0
                           insertCpe.setString(2, s.getVendor());
      -  553  0
                           insertCpe.setString(3, s.getProduct());
      -  554  0
                           insertCpe.executeUpdate();
      -  555  0
                           cpeProductId = DBUtils.getGeneratedKey(insertCpe);
      -  556   +  477   +
               try {
      +  478  0
                   selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID"));
      +  479  0
                   deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY"));
      +  480  0
                   deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE"));
      +  481  0
                   deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE"));
      +  482  0
                   updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY"));
      +  483  0
                   final String[] ids = {"id"};
      +  484  0
                   insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"),
      +  485   +
                           //Statement.RETURN_GENERATED_KEYS);
      +  486   +
                           ids);
      +  487  0
                   insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE"));
      +  488  0
                   selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID"));
      +  489  0
                   insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"),
      +  490   +
                           //Statement.RETURN_GENERATED_KEYS);
      +  491   +
                           ids);
      +  492  0
                   insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE"));
      +  493  0
                   int vulnerabilityId = 0;
      +  494  0
                   selectVulnerabilityId.setString(1, vuln.getName());
      +  495  0
                   ResultSet rs = selectVulnerabilityId.executeQuery();
      +  496  0
                   if (rs.next()) {
      +  497  0
                       vulnerabilityId = rs.getInt(1);
      +  498   +
                       // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier.
      +  499  0
                       deleteReferences.setInt(1, vulnerabilityId);
      +  500  0
                       deleteReferences.execute();
      +  501  0
                       deleteSoftware.setInt(1, vulnerabilityId);
      +  502  0
                       deleteSoftware.execute();
      +  503   +
                   }
      +  504  0
                   DBUtils.closeResultSet(rs);
      +  505  0
                   rs = null;
      +  506   +
       
      +  507  0
                   if (vulnerabilityId != 0) {
      +  508  0
                       if (vuln.getDescription().contains("** REJECT **")) {
      +  509  0
                           deleteVulnerability.setInt(1, vulnerabilityId);
      +  510  0
                           deleteVulnerability.executeUpdate();
      +  511   +
                       } else {
      +  512  0
                           updateVulnerability.setString(1, vuln.getDescription());
      +  513  0
                           updateVulnerability.setString(2, vuln.getCwe());
      +  514  0
                           updateVulnerability.setFloat(3, vuln.getCvssScore());
      +  515  0
                           updateVulnerability.setString(4, vuln.getCvssAccessVector());
      +  516  0
                           updateVulnerability.setString(5, vuln.getCvssAccessComplexity());
      +  517  0
                           updateVulnerability.setString(6, vuln.getCvssAuthentication());
      +  518  0
                           updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact());
      +  519  0
                           updateVulnerability.setString(8, vuln.getCvssIntegrityImpact());
      +  520  0
                           updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact());
      +  521  0
                           updateVulnerability.setInt(10, vulnerabilityId);
      +  522  0
                           updateVulnerability.executeUpdate();
      +  523  
                       }
      -  557  0
                       if (cpeProductId == 0) {
      -  558  0
                           throw new DatabaseException("Unable to retrieve cpeProductId - no data returned");
      +  524   +
                   } else {
      +  525  0
                       insertVulnerability.setString(1, vuln.getName());
      +  526  0
                       insertVulnerability.setString(2, vuln.getDescription());
      +  527  0
                       insertVulnerability.setString(3, vuln.getCwe());
      +  528  0
                       insertVulnerability.setFloat(4, vuln.getCvssScore());
      +  529  0
                       insertVulnerability.setString(5, vuln.getCvssAccessVector());
      +  530  0
                       insertVulnerability.setString(6, vuln.getCvssAccessComplexity());
      +  531  0
                       insertVulnerability.setString(7, vuln.getCvssAuthentication());
      +  532  0
                       insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact());
      +  533  0
                       insertVulnerability.setString(9, vuln.getCvssIntegrityImpact());
      +  534  0
                       insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact());
      +  535  0
                       insertVulnerability.execute();
      +  536   +
                       try {
      +  537  0
                           rs = insertVulnerability.getGeneratedKeys();
      +  538  0
                           rs.next();
      +  539  0
                           vulnerabilityId = rs.getInt(1);
      +  540  0
                       } catch (SQLException ex) {
      +  541  0
                           final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName());
      +  542  0
                           throw new DatabaseException(msg, ex);
      +  543   +
                       } finally {
      +  544  0
                           DBUtils.closeResultSet(rs);
      +  545  0
                           rs = null;
      +  546  0
                       }
      +  547   +
                   }
      +  548   +
       
      +  549  0
                   for (Reference r : vuln.getReferences()) {
      +  550  0
                       insertReference.setInt(1, vulnerabilityId);
      +  551  0
                       insertReference.setString(2, r.getName());
      +  552  0
                       insertReference.setString(3, r.getUrl());
      +  553  0
                       insertReference.setString(4, r.getSource());
      +  554   +
       
      +  555  0
                       if (batchSupported) {
      +  556  0
                           insertReference.addBatch();
      +  557   +
                       } else {
      +  558  0
                           insertReference.execute();
       559  
                       }
      -  560   +  560  0
                   }
      +  561  
       
      -  561  0
                       insertSoftware.setInt(1, vulnerabilityId);
      -  562  0
                       insertSoftware.setInt(2, cpeProductId);
      -  563  0
                       if (s.getPreviousVersion() == null) {
      -  564  0
                           insertSoftware.setNull(3, java.sql.Types.VARCHAR);
      +  562  0
                   if (batchSupported) {
      +  563  0
                       insertReference.executeBatch();
      +  564   +
                   }
       565   -
                       } else {
      -  566  0
                           insertSoftware.setString(3, s.getPreviousVersion());
      -  567   -
                       }
      -  568  0
                       insertSoftware.execute();
      -  569  0
                   }
      -  570  
       
      -  571  0
               } catch (SQLException ex) {
      -  572  0
                   final String msg = String.format("Error updating '%s'", vuln.getName());
      -  573  0
                   LOGGER.debug("", ex);
      -  574  0
                   throw new DatabaseException(msg, ex);
      -  575   -
               } finally {
      -  576  0
                   DBUtils.closeStatement(selectVulnerabilityId);
      -  577  0
                   DBUtils.closeStatement(deleteReferences);
      -  578  0
                   DBUtils.closeStatement(deleteSoftware);
      -  579  0
                   DBUtils.closeStatement(updateVulnerability);
      -  580  0
                   DBUtils.closeStatement(deleteVulnerability);
      -  581  0
                   DBUtils.closeStatement(insertVulnerability);
      -  582  0
                   DBUtils.closeStatement(insertReference);
      -  583  0
                   DBUtils.closeStatement(selectCpeId);
      -  584  0
                   DBUtils.closeStatement(insertCpe);
      -  585  0
                   DBUtils.closeStatement(insertSoftware);
      -  586  0
               }
      -  587  0
           }
      -  588   -
       
      -  589   -
           /**
      -  590   -
            * Checks to see if data exists so that analysis can be performed.
      -  591   -
            *
      -  592   -
            * @return <code>true</code> if data exists; otherwise <code>false</code>
      -  593   -
            */
      -  594   -
           public boolean dataExists() {
      -  595  1
               Statement cs = null;
      -  596  1
               ResultSet rs = null;
      -  597   -
               try {
      -  598  1
                   cs = conn.createStatement();
      -  599  1
                   rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry");
      -  600  1
                   if (rs.next()) {
      -  601  1
                       if (rs.getInt(1) > 0) {
      -  602  1
                           return true;
      -  603   -
                       }
      -  604   -
                   }
      -  605  0
               } catch (SQLException ex) {
      -  606   -
                   String dd;
      -  607   -
                   try {
      -  608  0
                       dd = Settings.getDataDirectory().getAbsolutePath();
      -  609  0
                   } catch (IOException ex1) {
      -  610  0
                       dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      -  611  0
                   }
      -  612  0
                   LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. "
      -  613   -
                           + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please "
      -  614   -
                           + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at "
      -  615   -
                           + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n",
      -  616  0
                           dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME));
      -  617  0
                   LOGGER.debug("", ex);
      -  618   -
               } finally {
      -  619  1
                   DBUtils.closeResultSet(rs);
      -  620  1
                   DBUtils.closeStatement(cs);
      -  621  0
               }
      -  622  0
               return false;
      -  623   -
           }
      -  624   -
       
      -  625   -
           /**
      -  626   -
            * It is possible that orphaned rows may be generated during database updates. This should be called after all updates have
      -  627   -
            * been completed to ensure orphan entries are removed.
      -  628   -
            */
      -  629   -
           public void cleanupDatabase() {
      -  630  0
               PreparedStatement ps = null;
      -  631   -
               try {
      -  632  0
                   ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS"));
      -  633  0
                   if (ps != null) {
      -  634  0
                       ps.executeUpdate();
      -  635   -
                   }
      -  636  0
               } catch (SQLException ex) {
      -  637  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      -  638  0
                   LOGGER.debug("", ex);
      -  639   -
               } finally {
      -  640  0
                   DBUtils.closeStatement(ps);
      -  641  0
               }
      -  642  0
           }
      -  643   -
       
      -  644   -
           /**
      -  645   -
            * Determines if the given identifiedVersion is affected by the given cpeId and previous version flag. A non-null, non-empty
      -  646   -
            * string passed to the previous version argument indicates that all previous versions are affected.
      -  647   -
            *
      -  648   -
            * @param vendor the vendor of the dependency being analyzed
      -  649   -
            * @param product the product name of the dependency being analyzed
      -  650   -
            * @param vulnerableSoftware a map of the vulnerable software with a boolean indicating if all previous versions are affected
      -  651   -
            * @param identifiedVersion the identified version of the dependency being analyzed
      -  652   -
            * @return true if the identified version is affected, otherwise false
      -  653   -
            */
      -  654   -
           Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product,
      -  655   -
                   DependencyVersion identifiedVersion) {
      -  656   -
       
      -  657  13
               final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
      -  658   -
       
      -  659  13
               final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>();
      -  660  13
               final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
      -  661  13
               String majorVersionMatch = null;
      -  662  13
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      -  663  279
                   final DependencyVersion v = parseDependencyVersion(entry.getKey());
      -  664  279
                   if (v == null || "-".equals(v.toString())) { //all versions
      -  665  0
                       return entry;
      -  666   -
                   }
      -  667  279
                   if (entry.getValue()) {
      -  668  8
                       if (matchesAnyPrevious) {
      -  669  0
                           return entry;
      -  670   -
                       }
      -  671  8
                       if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) {
      -  672  6
                           majorVersionMatch = v.getVersionParts().get(0);
      -  673   -
                       }
      -  674  8
                       majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0));
      -  675   -
                   }
      -  676  279
               }
      -  677  13
               if (matchesAnyPrevious) {
      -  678  0
                   return null;
      -  679   -
               }
      -  680   -
       
      -  681  13
               final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1;
      -  682   -
               //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions
      -  683   -
               //then later we process those that affect all versions. This could be done with sorting...
      -  684  13
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      -  685  237
                   if (!entry.getValue()) {
      -  686  229
                       final DependencyVersion v = parseDependencyVersion(entry.getKey());
      -  687   -
                       //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
      -  688  229
                       if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
      -  689  8
                           continue;
      -  690   -
                       }
      -  691   -
                       //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
      -  692   -
                       //in the above loop or just after loop (if matchesAnyPrevious return null).
      -  693  221
                       if (identifiedVersion.equals(v)) {
      -  694  8
                           return entry;
      -  695   -
                       }
      -  696   -
                   }
      -  697  221
               }
      -  698  5
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      -  699  56
                   if (entry.getValue()) {
      -  700  0
                       final DependencyVersion v = parseDependencyVersion(entry.getKey());
      -  701   -
                       //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
      -  702  0
                       if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
      -  703  0
                           continue;
      -  704   -
                       }
      -  705   -
                       //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
      -  706   -
                       //in the above loop or just after loop (if matchesAnyPrevious return null).
      -  707  0
                       if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) {
      -  708  0
                           if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) {
      -  709  0
                               return entry;
      -  710   +  566  0
                   for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
      +  567  0
                       int cpeProductId = 0;
      +  568  0
                       selectCpeId.setString(1, s.getName());
      +  569   +
                       try {
      +  570  0
                           rs = selectCpeId.executeQuery();
      +  571  0
                           if (rs.next()) {
      +  572  0
                               cpeProductId = rs.getInt(1);
      +  573  
                           }
      -  711   +  574  0
                       } catch (SQLException ex) {
      +  575  0
                           throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex);
      +  576   +
                       } finally {
      +  577  0
                           DBUtils.closeResultSet(rs);
      +  578  0
                           rs = null;
      +  579  0
                       }
      +  580   +
       
      +  581  0
                       if (cpeProductId == 0) {
      +  582  0
                           insertCpe.setString(1, s.getName());
      +  583  0
                           insertCpe.setString(2, s.getVendor());
      +  584  0
                           insertCpe.setString(3, s.getProduct());
      +  585  0
                           insertCpe.executeUpdate();
      +  586  0
                           cpeProductId = DBUtils.getGeneratedKey(insertCpe);
      +  587  
                       }
      -  712   +  588  0
                       if (cpeProductId == 0) {
      +  589  0
                           throw new DatabaseException("Unable to retrieve cpeProductId - no data returned");
      +  590   +
                       }
      +  591   +
       
      +  592  0
                       insertSoftware.setInt(1, vulnerabilityId);
      +  593  0
                       insertSoftware.setInt(2, cpeProductId);
      +  594   +
       
      +  595  0
                       if (s.getPreviousVersion() == null) {
      +  596  0
                           insertSoftware.setNull(3, java.sql.Types.VARCHAR);
      +  597   +
                       } else {
      +  598  0
                           insertSoftware.setString(3, s.getPreviousVersion());
      +  599   +
                       }
      +  600  0
                       if (batchSupported) {
      +  601  0
                           insertSoftware.addBatch();
      +  602   +
                       } else {
      +  603   +
                           try {
      +  604  0
                               insertSoftware.execute();
      +  605  0
                           } catch (SQLException ex) {
      +  606  0
                               if (ex.getMessage().contains("Duplicate entry")) {
      +  607  0
                                   final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName());
      +  608  0
                                   LOGGER.debug(msg, ex);
      +  609  0
                               } else {
      +  610  0
                                   throw ex;
      +  611   +
                               }
      +  612  0
                           }
      +  613   +
                       }
      +  614  0
                   }
      +  615  0
                   if (batchSupported) {
      +  616  0
                       insertSoftware.executeBatch();
      +  617  
                   }
      -  713  56
               }
      -  714  5
               return null;
      -  715   -
           }
      -  716   +  618  0
               } catch (SQLException ex) {
      +  619  0
                   final String msg = String.format("Error updating '%s'", vuln.getName());
      +  620  0
                   LOGGER.debug(msg, ex);
      +  621  0
                   throw new DatabaseException(msg, ex);
      +  622   +
               } finally {
      +  623  0
                   DBUtils.closeStatement(selectVulnerabilityId);
      +  624  0
                   DBUtils.closeStatement(deleteReferences);
      +  625  0
                   DBUtils.closeStatement(deleteSoftware);
      +  626  0
                   DBUtils.closeStatement(updateVulnerability);
      +  627  0
                   DBUtils.closeStatement(deleteVulnerability);
      +  628  0
                   DBUtils.closeStatement(insertVulnerability);
      +  629  0
                   DBUtils.closeStatement(insertReference);
      +  630  0
                   DBUtils.closeStatement(selectCpeId);
      +  631  0
                   DBUtils.closeStatement(insertCpe);
      +  632  0
                   DBUtils.closeStatement(insertSoftware);
      +  633  0
               }
      +  634  0
           }
      +  635  
       
      -  717   +  636  
           /**
      -  718   -
            * Parses the version (including revision) from a CPE identifier. If no version is identified then a '-' is returned.
      -  719   +  637   +
            * Checks to see if data exists so that analysis can be performed.
      +  638  
            *
      -  720   -
            * @param cpeStr a cpe identifier
      -  721   -
            * @return a dependency version
      -  722   +  639   +
            * @return <code>true</code> if data exists; otherwise <code>false</code>
      +  640  
            */
      -  723   -
           private DependencyVersion parseDependencyVersion(String cpeStr) {
      -  724  508
               final VulnerableSoftware cpe = new VulnerableSoftware();
      -  725   +  641   +
           public boolean dataExists() {
      +  642  4
               Statement cs = null;
      +  643  4
               ResultSet rs = null;
      +  644  
               try {
      -  726  508
                   cpe.parseName(cpeStr);
      -  727  0
               } catch (UnsupportedEncodingException ex) {
      -  728   -
                   //never going to happen.
      -  729  0
                   LOGGER.trace("", ex);
      -  730  508
               }
      -  731  508
               return parseDependencyVersion(cpe);
      -  732   +  645  4
                   cs = conn.createStatement();
      +  646  4
                   rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry");
      +  647  4
                   if (rs.next()) {
      +  648  4
                       if (rs.getInt(1) > 0) {
      +  649  8
                           return true;
      +  650   +
                       }
      +  651   +
                   }
      +  652  0
               } catch (SQLException ex) {
      +  653   +
                   String dd;
      +  654   +
                   try {
      +  655  0
                       dd = Settings.getDataDirectory().getAbsolutePath();
      +  656  0
                   } catch (IOException ex1) {
      +  657  0
                       dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      +  658  0
                   }
      +  659  0
                   LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. "
      +  660   +
                           + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please "
      +  661   +
                           + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at "
      +  662   +
                           + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n",
      +  663  0
                           dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME));
      +  664  0
                   LOGGER.debug("", ex);
      +  665   +
               } finally {
      +  666  4
                   DBUtils.closeResultSet(rs);
      +  667  4
                   DBUtils.closeStatement(cs);
      +  668  0
               }
      +  669  0
               return false;
      +  670  
           }
      -  733   +  671  
       
      -  734   +  672  
           /**
      -  735   -
            * Takes a CPE and parses out the version number. If no version is identified then a '-' is returned.
      -  736   -
            *
      -  737   -
            * @param cpe a cpe object
      -  738   -
            * @return a dependency version
      -  739   +  673   +
            * It is possible that orphaned rows may be generated during database
      +  674   +
            * updates. This should be called after all updates have been completed to
      +  675   +
            * ensure orphan entries are removed.
      +  676  
            */
      -  740   -
           private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) {
      -  741   -
               final DependencyVersion cpeVersion;
      -  742  511
               if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) {
      +  677   +
           public void cleanupDatabase() {
      +  678  0
               PreparedStatement ps = null;
      +  679   +
               try {
      +  680  0
                   ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS"));
      +  681  0
                   if (ps != null) {
      +  682  0
                       ps.executeUpdate();
      +  683   +
                   }
      +  684  0
               } catch (SQLException ex) {
      +  685  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      +  686  0
                   LOGGER.debug("", ex);
      +  687   +
               } finally {
      +  688  0
                   DBUtils.closeStatement(ps);
      +  689  0
               }
      +  690  0
           }
      +  691   +
       
      +  692   +
           /**
      +  693   +
            * Determines if the given identifiedVersion is affected by the given cpeId
      +  694   +
            * and previous version flag. A non-null, non-empty string passed to the
      +  695   +
            * previous version argument indicates that all previous versions are
      +  696   +
            * affected.
      +  697   +
            *
      +  698   +
            * @param vendor the vendor of the dependency being analyzed
      +  699   +
            * @param product the product name of the dependency being analyzed
      +  700   +
            * @param vulnerableSoftware a map of the vulnerable software with a boolean
      +  701   +
            * indicating if all previous versions are affected
      +  702   +
            * @param identifiedVersion the identified version of the dependency being
      +  703   +
            * analyzed
      +  704   +
            * @return true if the identified version is affected, otherwise false
      +  705   +
            */
      +  706   +
           Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product,
      +  707   +
                   DependencyVersion identifiedVersion) {
      +  708   +
       
      +  709  26
               final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
      +  710   +
       
      +  711  26
               final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>();
      +  712  26
               final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
      +  713  26
               String majorVersionMatch = null;
      +  714  26
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      +  715  558
                   final DependencyVersion v = parseDependencyVersion(entry.getKey());
      +  716  558
                   if (v == null || "-".equals(v.toString())) { //all versions
      +  717  0
                       return entry;
      +  718   +
                   }
      +  719  558
                   if (entry.getValue()) {
      +  720  16
                       if (matchesAnyPrevious) {
      +  721  0
                           return entry;
      +  722   +
                       }
      +  723  16
                       if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) {
      +  724  12
                           majorVersionMatch = v.getVersionParts().get(0);
      +  725   +
                       }
      +  726  16
                       majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0));
      +  727   +
                   }
      +  728  558
               }
      +  729  26
               if (matchesAnyPrevious) {
      +  730  0
                   return null;
      +  731   +
               }
      +  732   +
       
      +  733  26
               final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1;
      +  734   +
               //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions
      +  735   +
               //then later we process those that affect all versions. This could be done with sorting...
      +  736  26
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      +  737  474
                   if (!entry.getValue()) {
      +  738  458
                       final DependencyVersion v = parseDependencyVersion(entry.getKey());
      +  739   +
                       //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
      +  740  458
                       if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
      +  741  16
                           continue;
      +  742   +
                       }
       743   -
                   final String versionText;
      -  744  511
                   if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) {
      -  745  113
                       versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate());
      -  746   -
                   } else {
      -  747  398
                       versionText = cpe.getVersion();
      +
                       //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
      +  744   +
                       //in the above loop or just after loop (if matchesAnyPrevious return null).
      +  745  442
                       if (identifiedVersion.equals(v)) {
      +  746  16
                           return entry;
      +  747   +
                       }
       748  
                   }
      -  749  511
                   cpeVersion = DependencyVersionUtil.parseVersion(versionText);
      -  750  511
               } else {
      -  751  0
                   cpeVersion = new DependencyVersion("-");
      -  752   -
               }
      -  753  511
               return cpeVersion;
      -  754   -
           }
      -  755   -
       
      +  749  442
               }
      +  750  10
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      +  751  112
                   if (entry.getValue()) {
      +  752  0
                       final DependencyVersion v = parseDependencyVersion(entry.getKey());
      +  753   +
                       //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
      +  754  0
                       if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
      +  755  0
                           continue;
       756   -
           /**
      +
                       }
       757   -
            * This method is only referenced in unused code.
      +
                       //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
       758   -
            *
      -  759   -
            * Deletes unused dictionary entries from the database.
      -  760   -
            */
      -  761   -
           public void deleteUnusedCpe() {
      -  762  0
               CallableStatement cs = null;
      +
                       //in the above loop or just after loop (if matchesAnyPrevious return null).
      +  759  0
                       if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) {
      +  760  0
                           if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) {
      +  761  0
                               return entry;
      +  762   +
                           }
       763   -
               try {
      -  764  0
                   cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE"));
      -  765  0
                   cs.executeUpdate();
      -  766  0
               } catch (SQLException ex) {
      -  767  0
                   LOGGER.error("Unable to delete CPE dictionary entries", ex);
      +
                       }
      +  764   +
                   }
      +  765  112
               }
      +  766  10
               return null;
      +  767   +
           }
       768   -
               } finally {
      -  769  0
                   DBUtils.closeStatement(cs);
      -  770  0
               }
      -  771  0
           }
      -  772  
       
      -  773   +  769  
           /**
      +  770   +
            * Parses the version (including revision) from a CPE identifier. If no
      +  771   +
            * version is identified then a '-' is returned.
      +  772   +
            *
      +  773   +
            * @param cpeStr a cpe identifier
       774   -
            * This method is only referenced in unused code and will likely break on MySQL if ever used due to the MERGE statement.
      +
            * @return a dependency version
       775   -
            *
      -  776   -
            * Merges CPE entries into the database.
      -  777   -
            *
      -  778   -
            * @param cpe the CPE identifier
      -  779   -
            * @param vendor the CPE vendor
      -  780   -
            * @param product the CPE product
      -  781  
            */
      -  782   -
           public void addCpe(String cpe, String vendor, String product) {
      -  783  0
               PreparedStatement ps = null;
      -  784   +  776   +
           private DependencyVersion parseDependencyVersion(String cpeStr) {
      +  777  1016
               final VulnerableSoftware cpe = new VulnerableSoftware();
      +  778  
               try {
      -  785  0
                   ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE"));
      -  786  0
                   ps.setString(1, cpe);
      -  787  0
                   ps.setString(2, vendor);
      -  788  0
                   ps.setString(3, product);
      -  789  0
                   ps.executeUpdate();
      -  790  0
               } catch (SQLException ex) {
      -  791  0
                   LOGGER.error("Unable to add CPE dictionary entry", ex);
      +  779  1016
                   cpe.parseName(cpeStr);
      +  780  0
               } catch (UnsupportedEncodingException ex) {
      +  781   +
                   //never going to happen.
      +  782  0
                   LOGGER.trace("", ex);
      +  783  1016
               }
      +  784  1016
               return parseDependencyVersion(cpe);
      +  785   +
           }
      +  786   +
       
      +  787   +
           /**
      +  788   +
            * Takes a CPE and parses out the version number. If no version is
      +  789   +
            * identified then a '-' is returned.
      +  790   +
            *
      +  791   +
            * @param cpe a cpe object
       792   +
            * @return a dependency version
      +  793   +
            */
      +  794   +
           private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) {
      +  795   +
               final DependencyVersion cpeVersion;
      +  796  1022
               if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) {
      +  797   +
                   final String versionText;
      +  798  1022
                   if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) {
      +  799  226
                       versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate());
      +  800   +
                   } else {
      +  801  796
                       versionText = cpe.getVersion();
      +  802   +
                   }
      +  803  1022
                   cpeVersion = DependencyVersionUtil.parseVersion(versionText);
      +  804  1022
               } else {
      +  805  0
                   cpeVersion = new DependencyVersion("-");
      +  806   +
               }
      +  807  1022
               return cpeVersion;
      +  808   +
           }
      +  809   +
       
      +  810   +
           /**
      +  811   +
            * This method is only referenced in unused code.
      +  812   +
            *
      +  813   +
            * Deletes unused dictionary entries from the database.
      +  814   +
            */
      +  815   +
           public void deleteUnusedCpe() {
      +  816  0
               CallableStatement cs = null;
      +  817   +
               try {
      +  818  0
                   cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE"));
      +  819  0
                   cs.executeUpdate();
      +  820  0
               } catch (SQLException ex) {
      +  821  0
                   LOGGER.error("Unable to delete CPE dictionary entries", ex);
      +  822  
               } finally {
      -  793  0
                   DBUtils.closeStatement(ps);
      -  794  0
               }
      -  795  0
           }
      -  796   +  823  0
                   DBUtils.closeStatement(cs);
      +  824  0
               }
      +  825  0
           }
      +  826   +
       
      +  827   +
           /**
      +  828   +
            * This method is only referenced in unused code and will likely break on
      +  829   +
            * MySQL if ever used due to the MERGE statement.
      +  830   +
            *
      +  831   +
            * Merges CPE entries into the database.
      +  832   +
            *
      +  833   +
            * @param cpe the CPE identifier
      +  834   +
            * @param vendor the CPE vendor
      +  835   +
            * @param product the CPE product
      +  836   +
            */
      +  837   +
           public void addCpe(String cpe, String vendor, String product) {
      +  838  0
               PreparedStatement ps = null;
      +  839   +
               try {
      +  840  0
                   ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE"));
      +  841  0
                   ps.setString(1, cpe);
      +  842  0
                   ps.setString(2, vendor);
      +  843  0
                   ps.setString(3, product);
      +  844  0
                   ps.executeUpdate();
      +  845  0
               } catch (SQLException ex) {
      +  846  0
                   LOGGER.error("Unable to add CPE dictionary entry", ex);
      +  847   +
               } finally {
      +  848  0
                   DBUtils.closeStatement(ps);
      +  849  0
               }
      +  850  0
           }
      +  851  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseException.html index a3a694de4..409b13ce0 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseException.html @@ -131,6 +131,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.html index 1bf5d569e..ad662ca8c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.html @@ -99,7 +99,7 @@
            * The Logger.
       41  
            */
      -  42  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseProperties.class);
      +  42  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseProperties.class);
       43  
           /**
       44   @@ -182,10 +182,10 @@
            * @param cveDB the database object holding the properties
       83  
            */
      -  84  6
           DatabaseProperties(CveDB cveDB) {
      -  85  6
               this.cveDB = cveDB;
      -  86  6
               this.properties = cveDB.getProperties();
      -  87  6
           }
      +  84  26
           DatabaseProperties(CveDB cveDB) {
      +  85  26
               this.cveDB = cveDB;
      +  86  26
               this.properties = cveDB.getProperties();
      +  87  26
           }
       88  
       
       89   @@ -302,7 +302,7 @@
            */
       150  
           public Properties getProperties() {
      -  151  1
               return properties;
      +  151  2
               return properties;
       152  
           }
       153   @@ -352,6 +352,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoadException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoadException.html index 759d9c8de..b3eb3366f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoadException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoadException.html @@ -125,12 +125,12 @@
            */
       56  
           public DriverLoadException(String msg, Throwable ex) {
      -  57  3
               super(msg, ex);
      -  58  3
           }
      +  57  6
               super(msg, ex);
      +  58  6
           }
       59  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoader.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoader.html index 1895454c9..a681eeb81 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoader.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoader.html @@ -106,7 +106,7 @@
            * The logger.
       44  
            */
      -  45  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DriverLoader.class);
      +  45  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DriverLoader.class);
       46  
       
       47   @@ -135,8 +135,8 @@
            */
       60  
           public static Driver load(String className) throws DriverLoadException {
      -  61  4
               final ClassLoader loader = DriverLoader.class.getClassLoader(); //ClassLoader.getSystemClassLoader();
      -  62  4
               return load(className, loader);
      +  61  8
               final ClassLoader loader = DriverLoader.class.getClassLoader(); //ClassLoader.getSystemClassLoader();
      +  62  8
               return load(className, loader);
       63  
           }
       64   @@ -165,53 +165,53 @@
            */
       76  
           public static Driver load(String className, String pathToDriver) throws DriverLoadException {
      -  77  4
               final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader();
      -  78  4
               final List<URL> urls = new ArrayList<URL>();
      -  79  4
               final String[] paths = pathToDriver.split(File.pathSeparator);
      -  80  9
               for (String path : paths) {
      -  81  5
                   final File file = new File(path);
      -  82  5
                   if (file.isDirectory()) {
      -  83  2
                       final File[] files = file.listFiles();
      -  84  2
                       if (files != null) {
      -  85  38
                           for (File f : files) {
      +  77  8
               final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader();
      +  78  8
               final List<URL> urls = new ArrayList<URL>();
      +  79  8
               final String[] paths = pathToDriver.split(File.pathSeparator);
      +  80  18
               for (String path : paths) {
      +  81  10
                   final File file = new File(path);
      +  82  10
                   if (file.isDirectory()) {
      +  83  4
                       final File[] files = file.listFiles();
      +  84  4
                       if (files != null) {
      +  85  82
                           for (File f : files) {
       86  
                               try {
      -  87  36
                                   urls.add(f.toURI().toURL());
      +  87  78
                                   urls.add(f.toURI().toURL());
       88  0
                               } catch (MalformedURLException ex) {
       89  0
                                   LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'",
       90  0
                                           className, f.getAbsoluteFile(), ex);
       91  0
                                   throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex);
      -  92  36
                               }
      +  92  78
                               }
       93  
                           }
       94  
                       }
      -  95  2
                   } else if (file.exists()) {
      +  95  4
                   } else if (file.exists()) {
       96  
                       try {
      -  97  2
                           urls.add(file.toURI().toURL());
      +  97  4
                           urls.add(file.toURI().toURL());
       98  0
                       } catch (MalformedURLException ex) {
       99  0
                           LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'",
       100  0
                                   className, file.getAbsoluteFile(), ex);
       101  0
                           throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex);
      -  102  2
                       }
      +  102  4
                       }
       103  
                   }
       104  
               }
      -  105  4
               final URLClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() {
      +  105  8
               final URLClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() {
       106  
                   @Override
       107  
                   public URLClassLoader run() {
      -  108  4
                       return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
      +  108  8
                       return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
       109  
                   }
       110  
               });
       111  
       
      -  112  4
               return load(className, loader);
      +  112  8
               return load(className, loader);
       113  
           }
       114   @@ -236,19 +236,19 @@
           private static Driver load(String className, ClassLoader loader) throws DriverLoadException {
       124  
               try {
      -  125  8
                   final Class c = Class.forName(className, true, loader);
      +  125  16
                   final Class c = Class.forName(className, true, loader);
       126  
                   //final Class c = loader.loadClass(className);
      -  127  5
                   final Driver driver = (Driver) c.newInstance();
      -  128  5
                   final Driver shim = new DriverShim(driver);
      +  127  10
                   final Driver driver = (Driver) c.newInstance();
      +  128  10
                   final Driver shim = new DriverShim(driver);
       129  
                   //using the DriverShim to get around the fact that the DriverManager won't register a driver not in the base class path
      -  130  5
                   DriverManager.registerDriver(shim);
      -  131  5
                   return shim;
      -  132  3
               } catch (ClassNotFoundException ex) {
      -  133  3
                   final String msg = String.format("Unable to load database driver '%s'", className);
      -  134  3
                   LOGGER.debug(msg, ex);
      -  135  3
                   throw new DriverLoadException(msg, ex);
      +  130  10
                   DriverManager.registerDriver(shim);
      +  131  10
                   return shim;
      +  132  6
               } catch (ClassNotFoundException ex) {
      +  133  6
                   final String msg = String.format("Unable to load database driver '%s'", className);
      +  134  6
                   LOGGER.debug(msg, ex);
      +  135  6
                   throw new DriverLoadException(msg, ex);
       136  0
               } catch (InstantiationException ex) {
       137  0
                   final String msg = String.format("Unable to load database driver '%s'", className);
       138  0
                   LOGGER.debug(msg, ex);
      @@ -269,6 +269,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverShim.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverShim.html index cd7bbf1fd..27e61559d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverShim.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverShim.html @@ -107,7 +107,7 @@
            * The logger.
       45  
            */
      -  46  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DriverShim.class);
      +  46  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DriverShim.class);
       47  
           /**
       48   @@ -128,9 +128,9 @@
            * @param driver the database driver to wrap
       56  
            */
      -  57  5
           DriverShim(Driver driver) {
      -  58  5
               this.driver = driver;
      -  59  5
           }
      +  57  10
           DriverShim(Driver driver) {
      +  58  10
               this.driver = driver;
      +  59  10
           }
       60  
       
       61   @@ -155,7 +155,7 @@
           @Override
       71  
           public boolean acceptsURL(String url) throws SQLException {
      -  72  1
               return this.driver.acceptsURL(url);
      +  72  2
               return this.driver.acceptsURL(url);
       73  
           }
       74   @@ -387,13 +387,13 @@
           @Override
       202  
           public String toString() {
      -  203  9
               return "DriverShim{" + "driver=" + driver + '}';
      +  203  18
               return "DriverShim{" + "driver=" + driver + '}';
       204  
           }
       205  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html index e001139d9..f82c3a233 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  4
       public abstract class BaseUpdater {
      +  31  8
       public abstract class BaseUpdater {
       32  
       
       33   @@ -86,7 +86,7 @@
            * Static logger.
       35  
            */
      -  36  1
           private static final Logger LOGGER = LoggerFactory.getLogger(BaseUpdater.class);
      +  36  2
           private static final Logger LOGGER = LoggerFactory.getLogger(BaseUpdater.class);
       37  
           /**
       38   @@ -101,19 +101,19 @@
            * Reference to the Cve Database.
       43  
            */
      -  44  4
           private CveDB cveDB = null;
      +  44  8
           private CveDB cveDB = null;
       45  
       
       46  
           protected CveDB getCveDB() {
      -  47  1
               return cveDB;
      +  47  2
               return cveDB;
       48  
           }
       49  
       
       50  
           protected DatabaseProperties getProperties() {
      -  51  1
               return properties;
      +  51  2
               return properties;
       52  
           }
       53   @@ -126,18 +126,18 @@
            */
       57  
           protected void closeDataStores() {
      -  58  3
               if (cveDB != null) {
      +  58  6
               if (cveDB != null) {
       59  
                   try {
      -  60  3
                       cveDB.close();
      -  61  3
                       cveDB = null;
      -  62  3
                       properties = null;
      +  60  6
                       cveDB.close();
      +  61  6
                       cveDB = null;
      +  62  6
                       properties = null;
       63  0
                   } catch (Throwable ignore) {
       64  0
                       LOGGER.trace("Error closing the database", ignore);
      -  65  3
                   }
      +  65  6
                   }
       66  
               }
      -  67  3
           }
      +  67  6
           }
       68  
       
       69   @@ -152,25 +152,25 @@
            */
       74  
           protected final void openDataStores() throws UpdateException {
      -  75  3
               if (cveDB != null) {
      +  75  6
               if (cveDB != null) {
       76  0
                   return;
       77  
               }
       78  
               try {
      -  79  3
                   cveDB = new CveDB();
      -  80  3
                   cveDB.open();
      -  81  3
                   properties = cveDB.getDatabaseProperties();
      +  79  6
                   cveDB = new CveDB();
      +  80  6
                   cveDB.open();
      +  81  6
                   properties = cveDB.getDatabaseProperties();
       82  0
               } catch (DatabaseException ex) {
       83  0
                   closeDataStores();
       84  0
                   LOGGER.debug("Database Exception opening databases", ex);
       85  0
                   throw new UpdateException("Error updating the database, please see the log file for more details.");
      -  86  3
               }
      -  87  3
           }
      +  86  6
               }
      +  87  6
           }
       88  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CachedWebDataSource.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CachedWebDataSource.html index 36a27cefa..ae930fb2f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CachedWebDataSource.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CachedWebDataSource.html @@ -93,6 +93,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html index d9a8dec2f..397604c40 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html @@ -344,6 +344,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.EngineVersionCheck.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.EngineVersionCheck.html index 7900e0f9b..4bfc482cb 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.EngineVersionCheck.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.EngineVersionCheck.html @@ -99,7 +99,7 @@
        * @author Jeremy Long
       41  
        */
      -  42  2
       public class EngineVersionCheck implements CachedWebDataSource {
      +  42  4
       public class EngineVersionCheck implements CachedWebDataSource {
       43  
       
       44   @@ -108,7 +108,7 @@
            * Static logger.
       46  
            */
      -  47  1
           private static final Logger LOGGER = LoggerFactory.getLogger(EngineVersionCheck.class);
      +  47  2
           private static final Logger LOGGER = LoggerFactory.getLogger(EngineVersionCheck.class);
       48  
           /**
       49   @@ -131,7 +131,7 @@
            * Reference to the Cve Database.
       58  
            */
      -  59  2
           private CveDB cveDB = null;
      +  59  4
           private CveDB cveDB = null;
       60  
       
       61   @@ -173,8 +173,8 @@
            */
       80  
           protected void setUpdateToVersion(String version) {
      -  81  7
               updateToVersion = version;
      -  82  7
           }
      +  81  14
               updateToVersion = version;
      +  82  14
           }
       83  
       
       84   @@ -247,40 +247,40 @@
                   String currentVersion) throws UpdateException {
       129  
               //check every 30 days if we know there is an update, otherwise check every 7 days
      -  130  7
               final int checkRange = 30;
      -  131  7
               if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) {
      -  132  2
                   LOGGER.debug("Checking web for new version.");
      -  133  2
                   final String currentRelease = getCurrentReleaseVersion();
      -  134  2
                   if (currentRelease != null) {
      -  135  2
                       final DependencyVersion v = new DependencyVersion(currentRelease);
      -  136  2
                       if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) {
      -  137  2
                           updateToVersion = v.toString();
      -  138  2
                           if (!currentRelease.equals(updateToVersion)) {
      +  130  14
               final int checkRange = 30;
      +  131  14
               if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) {
      +  132  4
                   LOGGER.debug("Checking web for new version.");
      +  133  4
                   final String currentRelease = getCurrentReleaseVersion();
      +  134  4
                   if (currentRelease != null) {
      +  135  4
                       final DependencyVersion v = new DependencyVersion(currentRelease);
      +  136  4
                       if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) {
      +  137  4
                           updateToVersion = v.toString();
      +  138  4
                           if (!currentRelease.equals(updateToVersion)) {
       139  0
                               properties.save(CURRENT_ENGINE_RELEASE, updateToVersion);
       140  
                           }
      -  141  2
                           properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now));
      +  141  4
                           properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now));
       142  
                       }
       143  
                   }
      -  144  2
                   LOGGER.debug("Current Release: {}", updateToVersion);
      +  144  4
                   LOGGER.debug("Current Release: {}", updateToVersion);
       145  
               }
      -  146  7
               if (updateToVersion == null) {
      +  146  14
               if (updateToVersion == null) {
       147  0
                   LOGGER.debug("Unable to obtain current release");
       148  0
                   return false;
       149  
               }
      -  150  7
               final DependencyVersion running = new DependencyVersion(currentVersion);
      -  151  7
               final DependencyVersion released = new DependencyVersion(updateToVersion);
      -  152  7
               if (running.compareTo(released) < 0) {
      -  153  3
                   LOGGER.debug("Upgrade recommended");
      -  154  3
                   return true;
      +  150  14
               final DependencyVersion running = new DependencyVersion(currentVersion);
      +  151  14
               final DependencyVersion released = new DependencyVersion(updateToVersion);
      +  152  14
               if (running.compareTo(released) < 0) {
      +  153  6
                   LOGGER.debug("Upgrade recommended");
      +  154  6
                   return true;
       155  
               }
      -  156  4
               LOGGER.debug("Upgrade not needed");
      -  157  4
               return false;
      +  156  8
               LOGGER.debug("Upgrade not needed");
      +  157  8
               return false;
       158  
           }
       159   @@ -339,20 +339,20 @@
            */
       192  
           protected String getCurrentReleaseVersion() {
      -  193  3
               HttpURLConnection conn = null;
      +  193  6
               HttpURLConnection conn = null;
       194  
               try {
      -  195  3
                   final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt");
      -  196  3
                   final URL url = new URL(str);
      -  197  3
                   conn = URLConnectionFactory.createHttpURLConnection(url);
      -  198  3
                   conn.connect();
      -  199  3
                   if (conn.getResponseCode() != 200) {
      +  195  6
                   final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt");
      +  196  6
                   final URL url = new URL(str);
      +  197  6
                   conn = URLConnectionFactory.createHttpURLConnection(url);
      +  198  6
                   conn.connect();
      +  199  6
                   if (conn.getResponseCode() != 200) {
       200  0
                       return null;
       201  
                   }
      -  202  3
                   final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8");
      -  203  3
                   if (releaseVersion != null) {
      -  204  3
                       return releaseVersion.trim();
      +  202  6
                   final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8");
      +  203  6
                   if (releaseVersion != null) {
      +  204  12
                       return releaseVersion.trim();
       205  
                   }
       206  0
               } catch (MalformedURLException ex) {
      @@ -363,8 +363,8 @@  211  0
                   LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
       212  
               } finally {
      -  213  3
                   if (conn != null) {
      -  214  3
                       conn.disconnect();
      +  213  6
                   if (conn != null) {
      +  214  6
                       conn.disconnect();
       215  
                   }
       216   @@ -376,6 +376,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.NvdCveUpdater.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.NvdCveUpdater.html index a431d3529..aaa40c9b6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.NvdCveUpdater.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.NvdCveUpdater.html @@ -139,408 +139,434 @@  62  
            * <p>
       63   -
            * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.</p>
      +
            * Downloads the latest NVD CVE XML file from the web and imports it into
       64   -
            *
      +
            * the current CVE Database.</p>
       65   -
            * @throws UpdateException is thrown if there is an error updating the database
      +
            *
       66   -
            */
      +
            * @throws UpdateException is thrown if there is an error updating the
       67   -
           @Override
      -  68   -
           public void update() throws UpdateException {
      -  69   -
               try {
      -  70  0
                   openDataStores();
      -  71  0
                   boolean autoUpdate = true;
      -  72   -
                   try {
      -  73  0
                       autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
      -  74  0
                   } catch (InvalidSettingException ex) {
      -  75  0
                       LOGGER.debug("Invalid setting for auto-update; using true.");
      -  76  0
                   }
      -  77  0
                   if (autoUpdate && checkUpdate()) {
      -  78  0
                       final UpdateableNvdCve updateable = getUpdatesNeeded();
      -  79  0
                       if (updateable.isUpdateNeeded()) {
      -  80  0
                           performUpdate(updateable);
      -  81   -
                       }
      -  82   -
                   }
      -  83  0
               } catch (MalformedURLException ex) {
      -  84  0
                   LOGGER.warn(
      -  85   -
                           "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data.");
      -  86  0
                   LOGGER.debug("", ex);
      -  87  0
               } catch (DownloadFailedException ex) {
      -  88  0
                   LOGGER.warn(
      -  89   -
                           "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD.");
      -  90  0
                   if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
      -  91  0
                       LOGGER.info(
      -  92   -
                               "If you are behind a proxy you may need to configure dependency-check to use the proxy.");
      -  93   -
                   }
      -  94  0
                   LOGGER.debug("", ex);
      -  95   -
               } finally {
      -  96  0
                   closeDataStores();
      -  97  0
               }
      -  98  0
           }
      -  99   -
       
      -  100   -
           /**
      -  101   -
            * Checks if the NVD CVE XML files were last checked recently. As an optimization, we can avoid repetitive checks against the
      -  102   -
            * NVD. Setting CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before checking again. A database property
      -  103   -
            * stores the timestamp of the last check.
      -  104   -
            *
      -  105   -
            * @return true to proceed with the check, or false to skip.
      -  106   -
            * @throws UpdateException thrown when there is an issue checking for updates.
      -  107   -
            */
      -  108   -
           private boolean checkUpdate() throws UpdateException {
      -  109  0
               boolean proceed = true;
      -  110   -
               // If the valid setting has not been specified, then we proceed to check...
      -  111  0
               final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0);
      -  112  0
               if (dataExists() && 0 < validForHours) {
      -  113   -
                   // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec
      -  114  0
                   final long msValid = validForHours * 60L * 60L * 1000L;
      -  115  0
                   final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0"));
      -  116  0
                   final long now = System.currentTimeMillis();
      -  117  0
                   proceed = (now - lastChecked) > msValid;
      -  118  0
                   if (proceed) {
      -  119  0
                       getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(now));
      -  120   -
                   } else {
      -  121  0
                       LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours);
      -  122  0
                       LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.",
      -  123  0
                               lastChecked, now, msValid);
      -  124   -
                   }
      -  125   -
               }
      -  126  0
               return proceed;
      -  127   -
           }
      -  128   -
       
      -  129   -
           /**
      -  130   -
            * Checks the CVE Index to ensure data exists and analysis can continue.
      -  131   -
            *
      -  132   -
            * @return true if the database contains data
      -  133   -
            */
      -  134   -
           private boolean dataExists() {
      -  135  0
               CveDB cve = null;
      -  136   -
               try {
      -  137  0
                   cve = new CveDB();
      -  138  0
                   cve.open();
      -  139  0
                   return cve.dataExists();
      -  140  0
               } catch (DatabaseException ex) {
      -  141  0
                   return false;
      -  142   -
               } finally {
      -  143  0
                   if (cve != null) {
      -  144  0
                       cve.close();
      -  145   -
                   }
      -  146   -
               }
      -  147   -
           }
      -  148   -
       
      -  149   -
           /**
      -  150   -
            * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.
      -  151   -
            *
      -  152   -
            * @param updateable a collection of NVD CVE data file references that need to be downloaded and processed to update the
      -  153  
            * database
      -  154   -
            * @throws UpdateException is thrown if there is an error updating the database
      -  155   +  68  
            */
      -  156   -
           public void performUpdate(UpdateableNvdCve updateable) throws UpdateException {
      -  157  0
               int maxUpdates = 0;
      -  158   +  69   +
           @Override
      +  70   +
           public void update() throws UpdateException {
      +  71  
               try {
      -  159  0
                   for (NvdCveInfo cve : updateable) {
      -  160  0
                       if (cve.getNeedsUpdate()) {
      -  161  0
                           maxUpdates += 1;
      +  72  0
                   openDataStores();
      +  73  0
                   boolean autoUpdate = true;
      +  74   +
                   try {
      +  75  0
                       autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
      +  76  0
                   } catch (InvalidSettingException ex) {
      +  77  0
                       LOGGER.debug("Invalid setting for auto-update; using true.");
      +  78  0
                   }
      +  79  0
                   if (autoUpdate && checkUpdate()) {
      +  80  0
                       final UpdateableNvdCve updateable = getUpdatesNeeded();
      +  81  0
                       getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis()));
      +  82  0
                       if (updateable.isUpdateNeeded()) {
      +  83  0
                           performUpdate(updateable);
      +  84   +
                       }
      +  85   +
                   }
      +  86  0
               } catch (MalformedURLException ex) {
      +  87  0
                   LOGGER.warn(
      +  88   +
                           "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data.");
      +  89  0
                   LOGGER.debug("", ex);
      +  90  0
               } catch (DownloadFailedException ex) {
      +  91  0
                   LOGGER.warn(
      +  92   +
                           "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD.");
      +  93  0
                   if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
      +  94  0
                       LOGGER.info(
      +  95   +
                               "If you are behind a proxy you may need to configure dependency-check to use the proxy.");
      +  96   +
                   }
      +  97  0
                   LOGGER.debug("", ex);
      +  98   +
               } finally {
      +  99  0
                   closeDataStores();
      +  100  0
               }
      +  101  0
           }
      +  102   +
       
      +  103   +
           /**
      +  104   +
            * Checks if the NVD CVE XML files were last checked recently. As an
      +  105   +
            * optimization, we can avoid repetitive checks against the NVD. Setting
      +  106   +
            * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before
      +  107   +
            * checking again. A database property stores the timestamp of the last
      +  108   +
            * check.
      +  109   +
            *
      +  110   +
            * @return true to proceed with the check, or false to skip.
      +  111   +
            * @throws UpdateException thrown when there is an issue checking for
      +  112   +
            * updates.
      +  113   +
            */
      +  114   +
           private boolean checkUpdate() throws UpdateException {
      +  115  0
               boolean proceed = true;
      +  116   +
               // If the valid setting has not been specified, then we proceed to check...
      +  117  0
               final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0);
      +  118  0
               if (dataExists() && 0 < validForHours) {
      +  119   +
                   // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec
      +  120  0
                   final long msValid = validForHours * 60L * 60L * 1000L;
      +  121  0
                   final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0"));
      +  122  0
                   final long now = System.currentTimeMillis();
      +  123  0
                   proceed = (now - lastChecked) > msValid;
      +  124  0
                   if (!proceed) {
      +  125  0
                       LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours);
      +  126  0
                       LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.",
      +  127  0
                               lastChecked, now, msValid);
      +  128   +
                   }
      +  129   +
               }
      +  130  0
               return proceed;
      +  131   +
           }
      +  132   +
       
      +  133   +
           /**
      +  134   +
            * Checks the CVE Index to ensure data exists and analysis can continue.
      +  135   +
            *
      +  136   +
            * @return true if the database contains data
      +  137   +
            */
      +  138   +
           private boolean dataExists() {
      +  139  0
               CveDB cve = null;
      +  140   +
               try {
      +  141  0
                   cve = new CveDB();
      +  142  0
                   cve.open();
      +  143  0
                   return cve.dataExists();
      +  144  0
               } catch (DatabaseException ex) {
      +  145  0
                   return false;
      +  146   +
               } finally {
      +  147  0
                   if (cve != null) {
      +  148  0
                       cve.close();
      +  149   +
                   }
      +  150   +
               }
      +  151   +
           }
      +  152   +
       
      +  153   +
           /**
      +  154   +
            * Downloads the latest NVD CVE XML file from the web and imports it into
      +  155   +
            * the current CVE Database.
      +  156   +
            *
      +  157   +
            * @param updateable a collection of NVD CVE data file references that need
      +  158   +
            * to be downloaded and processed to update the database
      +  159   +
            * @throws UpdateException is thrown if there is an error updating the
      +  160   +
            * database
      +  161   +
            */
       162   +
           public void performUpdate(UpdateableNvdCve updateable) throws UpdateException {
      +  163  0
               int maxUpdates = 0;
      +  164   +
               try {
      +  165  0
                   for (NvdCveInfo cve : updateable) {
      +  166  0
                       if (cve.getNeedsUpdate()) {
      +  167  0
                           maxUpdates += 1;
      +  168  
                       }
      -  163  0
                   }
      -  164  0
                   if (maxUpdates <= 0) {
      -  165  0
                       return;
      -  166   +  169  0
                   }
      +  170  0
                   if (maxUpdates <= 0) {
      +  171  0
                       return;
      +  172  
                   }
      -  167  0
                   if (maxUpdates > 3) {
      -  168  0
                       LOGGER.info(
      -  169   +  173  0
                   if (maxUpdates > 3) {
      +  174  0
                       LOGGER.info(
      +  175  
                               "NVD CVE requires several updates; this could take a couple of minutes.");
      -  170   -
                   }
      -  171  0
                   if (maxUpdates > 0) {
      -  172  0
                       openDataStores();
      -  173   -
                   }
      -  174   -
       
      -  175  0
                   final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates;
       176   +
                   }
      +  177  0
                   if (maxUpdates > 0) {
      +  178  0
                       openDataStores();
      +  179   +
                   }
      +  180  
       
      -  177  0
                   final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize);
      -  178  0
                   final ExecutorService processExecutor = Executors.newSingleThreadExecutor();
      -  179  0
                   final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates);
      -  180  0
                   for (NvdCveInfo cve : updateable) {
      -  181  0
                       if (cve.getNeedsUpdate()) {
      -  182  0
                           final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance());
      -  183  0
                           downloadFutures.add(downloadExecutors.submit(call));
      -  184   +  181  0
                   final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates;
      +  182   +
       
      +  183  0
                   final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize);
      +  184  0
                   final ExecutorService processExecutor = Executors.newSingleThreadExecutor();
      +  185  0
                   final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates);
      +  186  0
                   for (NvdCveInfo cve : updateable) {
      +  187  0
                       if (cve.getNeedsUpdate()) {
      +  188  0
                           final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance());
      +  189  0
                           downloadFutures.add(downloadExecutors.submit(call));
      +  190  
                       }
      -  185  0
                   }
      -  186  0
                   downloadExecutors.shutdown();
      -  187   +  191  0
                   }
      +  192  0
                   downloadExecutors.shutdown();
      +  193  
       
      -  188   +  194  
                   //next, move the future future processTasks to just future processTasks
      -  189  0
                   final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates);
      -  190  0
                   for (Future<Future<ProcessTask>> future : downloadFutures) {
      -  191  0
                       Future<ProcessTask> task = null;
      -  192   +  195  0
                   final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates);
      +  196  0
                   for (Future<Future<ProcessTask>> future : downloadFutures) {
      +  197  0
                       Future<ProcessTask> task = null;
      +  198  
                       try {
      -  193  0
                           task = future.get();
      -  194  0
                       } catch (InterruptedException ex) {
      -  195  0
                           downloadExecutors.shutdownNow();
      -  196  0
                           processExecutor.shutdownNow();
      -  197   -
       
      -  198  0
                           LOGGER.debug("Thread was interrupted during download", ex);
      -  199  0
                           throw new UpdateException("The download was interrupted", ex);
      -  200  0
                       } catch (ExecutionException ex) {
      +  199  0
                           task = future.get();
      +  200  0
                       } catch (InterruptedException ex) {
       201  0
                           downloadExecutors.shutdownNow();
       202  0
                           processExecutor.shutdownNow();
       203  
       
      -  204  0
                           LOGGER.debug("Thread was interrupted during download execution", ex);
      -  205  0
                           throw new UpdateException("The execution of the download was interrupted", ex);
      -  206  0
                       }
      -  207  0
                       if (task == null) {
      -  208  0
                           downloadExecutors.shutdownNow();
      -  209  0
                           processExecutor.shutdownNow();
      -  210  0
                           LOGGER.debug("Thread was interrupted during download");
      -  211  0
                           throw new UpdateException("The download was interrupted; unable to complete the update");
      -  212   -
                       } else {
      -  213  0
                           processFutures.add(task);
      -  214   -
                       }
      -  215  0
                   }
      -  216   +  204  0
                           LOGGER.debug("Thread was interrupted during download", ex);
      +  205  0
                           throw new UpdateException("The download was interrupted", ex);
      +  206  0
                       } catch (ExecutionException ex) {
      +  207  0
                           downloadExecutors.shutdownNow();
      +  208  0
                           processExecutor.shutdownNow();
      +  209  
       
      -  217  0
                   for (Future<ProcessTask> future : processFutures) {
      +  210  0
                           LOGGER.debug("Thread was interrupted during download execution", ex);
      +  211  0
                           throw new UpdateException("The execution of the download was interrupted", ex);
      +  212  0
                       }
      +  213  0
                       if (task == null) {
      +  214  0
                           downloadExecutors.shutdownNow();
      +  215  0
                           processExecutor.shutdownNow();
      +  216  0
                           LOGGER.debug("Thread was interrupted during download");
      +  217  0
                           throw new UpdateException("The download was interrupted; unable to complete the update");
       218   -
                       try {
      -  219  0
                           final ProcessTask task = future.get();
      -  220  0
                           if (task.getException() != null) {
      -  221  0
                               throw task.getException();
      -  222   -
                           }
      -  223  0
                       } catch (InterruptedException ex) {
      -  224  0
                           processExecutor.shutdownNow();
      -  225  0
                           LOGGER.debug("Thread was interrupted during processing", ex);
      -  226  0
                           throw new UpdateException(ex);
      -  227  0
                       } catch (ExecutionException ex) {
      -  228  0
                           processExecutor.shutdownNow();
      -  229  0
                           LOGGER.debug("Execution Exception during process", ex);
      -  230  0
                           throw new UpdateException(ex);
      -  231   -
                       } finally {
      -  232  0
                           processExecutor.shutdown();
      -  233  0
                       }
      -  234  0
                   }
      -  235   -
       
      -  236  0
                   if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it)
      -  237  0
                       getProperties().save(updateable.get(MODIFIED));
      -  238  0
                       LOGGER.info("Begin database maintenance.");
      -  239  0
                       getCveDB().cleanupDatabase();
      -  240  0
                       LOGGER.info("End database maintenance.");
      -  241   -
                   }
      -  242   -
               } finally {
      -  243  0
                   closeDataStores();
      -  244  0
               }
      -  245  0
           }
      -  246   -
       
      -  247   -
           /**
      -  248   -
            * Determines if the index needs to be updated. This is done by fetching the NVD CVE meta data and checking the last update
      -  249   -
            * date. If the data needs to be refreshed this method will return the NvdCveUrl for the files that need to be updated.
      -  250   -
            *
      -  251   -
            * @return the collection of files that need to be updated
      -  252   -
            * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta data is incorrect
      -  253   -
            * @throws DownloadFailedException is thrown if there is an error. downloading the NVD CVE download data file
      -  254   -
            * @throws UpdateException Is thrown if there is an issue with the last updated properties file
      -  255   -
            */
      -  256   -
           protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException {
      -  257  0
               UpdateableNvdCve updates = null;
      -  258   -
               try {
      -  259  0
                   updates = retrieveCurrentTimestampsFromWeb();
      -  260  0
               } catch (InvalidDataException ex) {
      -  261  0
                   final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page";
      -  262  0
                   LOGGER.debug(msg, ex);
      -  263  0
                   throw new DownloadFailedException(msg, ex);
      -  264  0
               } catch (InvalidSettingException ex) {
      -  265  0
                   LOGGER.debug("Invalid setting found when retrieving timestamps", ex);
      -  266  0
                   throw new DownloadFailedException("Invalid settings", ex);
      -  267  0
               }
      -  268   -
       
      -  269  0
               if (updates == null) {
      -  270  0
                   throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data");
      -  271   -
               }
      -  272  0
               if (!getProperties().isEmpty()) {
      -  273   -
                   try {
      -  274  0
                       final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0"));
      -  275  0
                       final long now = System.currentTimeMillis();
      -  276  0
                       final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7);
      -  277  0
                       if (lastUpdated == updates.getTimeStamp(MODIFIED)) {
      -  278  0
                           updates.clear(); //we don't need to update anything.
      -  279  0
                       } else if (DateUtil.withinDateRange(lastUpdated, now, days)) {
      -  280  0
                           for (NvdCveInfo entry : updates) {
      -  281  0
                               if (MODIFIED.equals(entry.getId())) {
      -  282  0
                                   entry.setNeedsUpdate(true);
      -  283   -
                               } else {
      -  284  0
                                   entry.setNeedsUpdate(false);
      -  285   -
                               }
      -  286  0
                           }
      -  287   -
                       } else { //we figure out which of the several XML files need to be downloaded.
      -  288  0
                           for (NvdCveInfo entry : updates) {
      -  289  0
                               if (MODIFIED.equals(entry.getId())) {
      -  290  0
                                   entry.setNeedsUpdate(true);
      -  291   -
                               } else {
      -  292  0
                                   long currentTimestamp = 0;
      -  293   -
                                   try {
      -  294  0
                                       currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE
      -  295  0
                                               + entry.getId(), "0"));
      -  296  0
                                   } catch (NumberFormatException ex) {
      -  297  0
                                       LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated",
      -  298  0
                                               DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex);
      -  299  0
                                   }
      -  300  0
                                   if (currentTimestamp == entry.getTimestamp()) {
      -  301  0
                                       entry.setNeedsUpdate(false);
      -  302   -
                                   }
      -  303   -
                               }
      -  304  0
                           }
      -  305   +
                       } else {
      +  219  0
                           processFutures.add(task);
      +  220  
                       }
      -  306  0
                   } catch (NumberFormatException ex) {
      -  307  0
                       LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file.");
      -  308  0
                       LOGGER.debug("", ex);
      -  309  0
                   }
      -  310   -
               }
      -  311  0
               return updates;
      -  312   -
           }
      -  313   +  221  0
                   }
      +  222  
       
      -  314   +  223  0
                   for (Future<ProcessTask> future : processFutures) {
      +  224   +
                       try {
      +  225  0
                           final ProcessTask task = future.get();
      +  226  0
                           if (task.getException() != null) {
      +  227  0
                               throw task.getException();
      +  228   +
                           }
      +  229  0
                       } catch (InterruptedException ex) {
      +  230  0
                           processExecutor.shutdownNow();
      +  231  0
                           LOGGER.debug("Thread was interrupted during processing", ex);
      +  232  0
                           throw new UpdateException(ex);
      +  233  0
                       } catch (ExecutionException ex) {
      +  234  0
                           processExecutor.shutdownNow();
      +  235  0
                           LOGGER.debug("Execution Exception during process", ex);
      +  236  0
                           throw new UpdateException(ex);
      +  237   +
                       } finally {
      +  238  0
                           processExecutor.shutdown();
      +  239  0
                       }
      +  240  0
                   }
      +  241   +
       
      +  242  0
                   if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it)
      +  243  0
                       getProperties().save(updateable.get(MODIFIED));
      +  244  0
                       LOGGER.info("Begin database maintenance.");
      +  245  0
                       getCveDB().cleanupDatabase();
      +  246  0
                       LOGGER.info("End database maintenance.");
      +  247   +
                   }
      +  248   +
               } finally {
      +  249  0
                   closeDataStores();
      +  250  0
               }
      +  251  0
           }
      +  252   +
       
      +  253  
           /**
      -  315   -
            * Retrieves the timestamps from the NVD CVE meta data file.
      -  316   +  254   +
            * Determines if the index needs to be updated. This is done by fetching the
      +  255   +
            * NVD CVE meta data and checking the last update date. If the data needs to
      +  256   +
            * be refreshed this method will return the NvdCveUrl for the files that
      +  257   +
            * need to be updated.
      +  258  
            *
      -  317   -
            * @return the timestamp from the currently published nvdcve downloads page
      -  318   -
            * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data is incorrect.
      -  319   -
            * @throws DownloadFailedException thrown if there is an error downloading the nvd cve meta data file
      -  320   -
            * @throws InvalidDataException thrown if there is an exception parsing the timestamps
      -  321   -
            * @throws InvalidSettingException thrown if the settings are invalid
      -  322   +  259   +
            * @return the collection of files that need to be updated
      +  260   +
            * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta
      +  261   +
            * data is incorrect
      +  262   +
            * @throws DownloadFailedException is thrown if there is an error.
      +  263   +
            * downloading the NVD CVE download data file
      +  264   +
            * @throws UpdateException Is thrown if there is an issue with the last
      +  265   +
            * updated properties file
      +  266  
            */
      -  323   -
           private UpdateableNvdCve retrieveCurrentTimestampsFromWeb()
      -  324   -
                   throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException {
      -  325   +  267   +
           protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException {
      +  268  0
               UpdateableNvdCve updates = null;
      +  269   +
               try {
      +  270  0
                   updates = retrieveCurrentTimestampsFromWeb();
      +  271  0
               } catch (InvalidDataException ex) {
      +  272  0
                   final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page";
      +  273  0
                   LOGGER.debug(msg, ex);
      +  274  0
                   throw new DownloadFailedException(msg, ex);
      +  275  0
               } catch (InvalidSettingException ex) {
      +  276  0
                   LOGGER.debug("Invalid setting found when retrieving timestamps", ex);
      +  277  0
                   throw new DownloadFailedException("Invalid settings", ex);
      +  278  0
               }
      +  279  
       
      -  326  0
               final UpdateableNvdCve updates = new UpdateableNvdCve();
      -  327  0
               updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL),
      -  328  0
                       Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL),
      -  329   -
                       false);
      -  330   -
       
      -  331  0
               final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR);
      -  332  0
               final int end = Calendar.getInstance().get(Calendar.YEAR);
      -  333  0
               final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0);
      -  334  0
               final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2);
      -  335  0
               for (int i = start; i <= end; i++) {
      -  336  0
                   updates.add(Integer.toString(i), String.format(baseUrl20, i),
      -  337  0
                           String.format(baseUrl12, i),
      -  338   -
                           true);
      -  339   +  280  0
               if (updates == null) {
      +  281  0
                   throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data");
      +  282  
               }
      -  340  0
               return updates;
      -  341   +  283  0
               if (!getProperties().isEmpty()) {
      +  284   +
                   try {
      +  285  0
                       final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0"));
      +  286  0
                       final long now = System.currentTimeMillis();
      +  287  0
                       final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7);
      +  288  0
                       if (lastUpdated == updates.getTimeStamp(MODIFIED)) {
      +  289  0
                           updates.clear(); //we don't need to update anything.
      +  290  0
                       } else if (DateUtil.withinDateRange(lastUpdated, now, days)) {
      +  291  0
                           for (NvdCveInfo entry : updates) {
      +  292  0
                               if (MODIFIED.equals(entry.getId())) {
      +  293  0
                                   entry.setNeedsUpdate(true);
      +  294   +
                               } else {
      +  295  0
                                   entry.setNeedsUpdate(false);
      +  296   +
                               }
      +  297  0
                           }
      +  298   +
                       } else { //we figure out which of the several XML files need to be downloaded.
      +  299  0
                           for (NvdCveInfo entry : updates) {
      +  300  0
                               if (MODIFIED.equals(entry.getId())) {
      +  301  0
                                   entry.setNeedsUpdate(true);
      +  302   +
                               } else {
      +  303  0
                                   long currentTimestamp = 0;
      +  304   +
                                   try {
      +  305  0
                                       currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE
      +  306  0
                                               + entry.getId(), "0"));
      +  307  0
                                   } catch (NumberFormatException ex) {
      +  308  0
                                       LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated",
      +  309  0
                                               DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex);
      +  310  0
                                   }
      +  311  0
                                   if (currentTimestamp == entry.getTimestamp()) {
      +  312  0
                                       entry.setNeedsUpdate(false);
      +  313   +
                                   }
      +  314   +
                               }
      +  315  0
                           }
      +  316   +
                       }
      +  317  0
                   } catch (NumberFormatException ex) {
      +  318  0
                       LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file.");
      +  319  0
                       LOGGER.debug("", ex);
      +  320  0
                   }
      +  321   +
               }
      +  322  0
               return updates;
      +  323  
           }
      -  342   +  324  
       
      +  325   +
           /**
      +  326   +
            * Retrieves the timestamps from the NVD CVE meta data file.
      +  327   +
            *
      +  328   +
            * @return the timestamp from the currently published nvdcve downloads page
      +  329   +
            * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data
      +  330   +
            * is incorrect.
      +  331   +
            * @throws DownloadFailedException thrown if there is an error downloading
      +  332   +
            * the nvd cve meta data file
      +  333   +
            * @throws InvalidDataException thrown if there is an exception parsing the
      +  334   +
            * timestamps
      +  335   +
            * @throws InvalidSettingException thrown if the settings are invalid
      +  336   +
            */
      +  337   +
           private UpdateableNvdCve retrieveCurrentTimestampsFromWeb()
      +  338   +
                   throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException {
      +  339   +
       
      +  340  0
               final UpdateableNvdCve updates = new UpdateableNvdCve();
      +  341  0
               updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL),
      +  342  0
                       Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL),
       343   +
                       false);
      +  344   +
       
      +  345  0
               final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR);
      +  346  0
               final int end = Calendar.getInstance().get(Calendar.YEAR);
      +  347  0
               final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0);
      +  348  0
               final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2);
      +  349  0
               for (int i = start; i <= end; i++) {
      +  350  0
                   updates.add(Integer.toString(i), String.format(baseUrl20, i),
      +  351  0
                           String.format(baseUrl12, i),
      +  352   +
                           true);
      +  353   +
               }
      +  354  0
               return updates;
      +  355   +
           }
      +  356  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.UpdateService.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.UpdateService.html index 3e61158fa..e9dd2ba02 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.UpdateService.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.UpdateService.html @@ -121,6 +121,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html index ba6882f58..80d4976ad 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      CPEHandler
      0%
      0/31
      0%
      0/16
      1.611
      CPEHandler
      0%
      0/30
      0%
      0/16
      1.611
      CPEHandler$Element
      0%
      0/17
      N/A
      1.611
      @@ -701,6 +701,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html index 26f217a06..4e1980116 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html @@ -251,6 +251,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.InvalidDataException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.InvalidDataException.html index acf4c9845..a4edfd858 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.InvalidDataException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.InvalidDataException.html @@ -115,6 +115,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.UpdateException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.UpdateException.html index 88d2c500b..3e684e6b1 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.UpdateException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.UpdateException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html index 43da95402..0133e2d04 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      DownloadTask
      55%
      61/109
      31%
      22/70
      5.636
      DownloadTask
      55%
      61/110
      31%
      22/70
      5.636
       
      @@ -114,7 +114,7 @@
            * The Logger.
       49  
            */
      -  50  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DownloadTask.class);
      +  50  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DownloadTask.class);
       51  
       
       52   @@ -137,11 +137,11 @@
            * @throws UpdateException thrown if temporary files could not be created
       61  
            */
      -  62  1
           public DownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
      -  63  1
               this.nvdCveInfo = nvdCveInfo;
      -  64  1
               this.processorService = processor;
      -  65  1
               this.cveDB = cveDB;
      -  66  1
               this.settings = settings;
      +  62  2
           public DownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
      +  63  2
               this.nvdCveInfo = nvdCveInfo;
      +  64  2
               this.processorService = processor;
      +  65  2
               this.cveDB = cveDB;
      +  66  2
               this.settings = settings;
       67  
       
       68   @@ -152,16 +152,16 @@
       
       71  
               try {
      -  72  1
                   file1 = File.createTempFile("cve" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
      -  73  1
                   file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
      +  72  2
                   file1 = File.createTempFile("cve" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
      +  73  2
                   file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
       74  0
               } catch (IOException ex) {
       75  0
                   throw new UpdateException("Unable to create temporary files", ex);
      -  76  1
               }
      -  77  1
               this.first = file1;
      -  78  1
               this.second = file2;
      +  76  2
               }
      +  77  2
               this.first = file1;
      +  78  2
               this.second = file2;
       79  
       
      -  80  1
           }
      +  80  2
           }
       81  
           /**
       82   @@ -317,15 +317,15 @@
           public Future<ProcessTask> call() throws Exception {
       162  
               try {
      -  163  1
                   Settings.setInstance(settings);
      -  164  1
                   final URL url1 = new URL(nvdCveInfo.getUrl());
      -  165  1
                   final URL url2 = new URL(nvdCveInfo.getOldSchemaVersionUrl());
      -  166  1
                   LOGGER.info("Download Started for NVD CVE - {}", nvdCveInfo.getId());
      -  167  1
                   final long startDownload = System.currentTimeMillis();
      +  163  2
                   Settings.setInstance(settings);
      +  164  2
                   final URL url1 = new URL(nvdCveInfo.getUrl());
      +  165  2
                   final URL url2 = new URL(nvdCveInfo.getOldSchemaVersionUrl());
      +  166  2
                   LOGGER.info("Download Started for NVD CVE - {}", nvdCveInfo.getId());
      +  167  2
                   final long startDownload = System.currentTimeMillis();
       168  
                   try {
      -  169  1
                       Downloader.fetchFile(url1, first);
      -  170  1
                       Downloader.fetchFile(url2, second);
      +  169  2
                       Downloader.fetchFile(url1, first);
      +  170  2
                       Downloader.fetchFile(url2, second);
       171  0
                   } catch (DownloadFailedException ex) {
       172  0
                       LOGGER.warn("Download Failed for NVD CVE - {}\nSome CVEs may not be reported.", nvdCveInfo.getId());
       173  0
                       if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
      @@ -336,21 +336,21 @@
                       }
       177  0
                       LOGGER.debug("", ex);
       178  0
                       return null;
      -  179  1
                   }
      -  180  1
                   if (url1.toExternalForm().endsWith(".xml.gz") && !isXml(first)) {
      -  181  1
                       extractGzip(first);
      +  179  2
                   }
      +  180  2
                   if (url1.toExternalForm().endsWith(".xml.gz") && !isXml(first)) {
      +  181  2
                       extractGzip(first);
       182  
                   }
      -  183  1
                   if (url2.toExternalForm().endsWith(".xml.gz") && !isXml(second)) {
      -  184  1
                       extractGzip(second);
      +  183  2
                   if (url2.toExternalForm().endsWith(".xml.gz") && !isXml(second)) {
      +  184  2
                       extractGzip(second);
       185  
                   }
       186  
       
      -  187  2
                   LOGGER.info("Download Complete for NVD CVE - {}  ({} ms)", nvdCveInfo.getId(),
      -  188  1
                           System.currentTimeMillis() - startDownload);
      -  189  1
                   if (this.processorService == null) {
      -  190  1
                       return null;
      +  187  4
                   LOGGER.info("Download Complete for NVD CVE - {}  ({} ms)", nvdCveInfo.getId(),
      +  188  2
                           System.currentTimeMillis() - startDownload);
      +  189  2
                   if (this.processorService == null) {
      +  190  4
                       return null;
       191  
                   }
       192  0
                   final ProcessTask task = new ProcessTask(cveDB, this, settings);
      @@ -362,7 +362,7 @@  197  0
                   LOGGER.debug("Download Task Failed", ex);
       198  
               } finally {
      -  199  1
                   Settings.cleanup(false);
      +  199  2
                   Settings.cleanup(false);
       200  0
               }
       201  0
               return null;
       202   @@ -424,25 +424,25 @@
            */
       236  
           public static boolean isXml(File file) {
      -  237  4
               if (file == null || !file.isFile()) {
      +  237  8
               if (file == null || !file.isFile()) {
       238  0
                   return false;
       239  
               }
      -  240  4
               InputStream is = null;
      +  240  8
               InputStream is = null;
       241  
               try {
      -  242  4
                   is = new FileInputStream(file);
      +  242  8
                   is = new FileInputStream(file);
       243  
       
      -  244  4
                   final byte[] buf = new byte[5];
      -  245  4
                   int read = 0;
      +  244  8
                   final byte[] buf = new byte[5];
      +  245  8
                   int read = 0;
       246  
                   try {
      -  247  4
                       read = is.read(buf);
      +  247  8
                       read = is.read(buf);
       248  0
                   } catch (IOException ex) {
       249  0
                       return false;
      -  250  4
                   }
      -  251  4
                   return read == 5
      +  250  8
                   }
      +  251  16
                   return read == 5
       252  
                           && buf[0] == '<'
       253   @@ -457,97 +457,98 @@  258  0
                   return false;
       259  
               } finally {
      -  260  4
                   if (is != null) {
      +  260  8
                   if (is != null) {
       261  
                       try {
      -  262  4
                           is.close();
      +  262  8
                           is.close();
       263  0
                       } catch (IOException ex) {
      -  264  8
                       }
      -  265   -
                   }
      +  264  0
                           LOGGER.debug("Error closing stream", ex);
      +  265  8
                       }
       266   -
               }
      +
                   }
       267   -
           }
      +
               }
       268   -
       
      +
           }
       269   -
           /**
      +
       
       270   -
            * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified.
      +
           /**
       271   -
            *
      +
            * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified.
       272   -
            * @param file the archive file
      +
            *
       273   -
            * @throws FileNotFoundException thrown if the file does not exist
      +
            * @param file the archive file
       274   -
            * @throws IOException thrown if there is an error extracting the file.
      +
            * @throws FileNotFoundException thrown if the file does not exist
       275   -
            */
      +
            * @throws IOException thrown if there is an error extracting the file.
       276   +
            */
      +  277  
           private void extractGzip(File file) throws FileNotFoundException, IOException {
      -  277  2
               final String originalPath = file.getPath();
      -  278  2
               final File gzip = new File(originalPath + ".gz");
      -  279  2
               if (gzip.isFile() && !gzip.delete()) {
      -  280  0
                   gzip.deleteOnExit();
      -  281   +  278  4
               final String originalPath = file.getPath();
      +  279  4
               final File gzip = new File(originalPath + ".gz");
      +  280  4
               if (gzip.isFile() && !gzip.delete()) {
      +  281  0
                   gzip.deleteOnExit();
      +  282  
               }
      -  282  2
               if (!file.renameTo(gzip)) {
      -  283  0
                   throw new IOException("Unable to rename '" + file.getPath() + "'");
      -  284   +  283  4
               if (!file.renameTo(gzip)) {
      +  284  0
                   throw new IOException("Unable to rename '" + file.getPath() + "'");
      +  285  
               }
      -  285  2
               final File newfile = new File(originalPath);
      -  286   +  286  4
               final File newfile = new File(originalPath);
      +  287  
       
      -  287  2
               final byte[] buffer = new byte[4096];
      -  288   +  288  4
               final byte[] buffer = new byte[4096];
      +  289  
       
      -  289  2
               GZIPInputStream cin = null;
      -  290  2
               FileOutputStream out = null;
      -  291   +  290  4
               GZIPInputStream cin = null;
      +  291  4
               FileOutputStream out = null;
      +  292  
               try {
      -  292  2
                   cin = new GZIPInputStream(new FileInputStream(gzip));
      -  293  2
                   out = new FileOutputStream(newfile);
      -  294   -
       
      +  293  4
                   cin = new GZIPInputStream(new FileInputStream(gzip));
      +  294  4
                   out = new FileOutputStream(newfile);
       295   +
       
      +  296  
                   int len;
      -  296  1154
                   while ((len = cin.read(buffer)) > 0) {
      -  297  1152
                       out.write(buffer, 0, len);
      -  298   -
                   }
      +  297  3366
                   while ((len = cin.read(buffer)) > 0) {
      +  298  3362
                       out.write(buffer, 0, len);
       299   +
                   }
      +  300  
               } finally {
      -  300  2
                   if (cin != null) {
      -  301   +  301  4
                   if (cin != null) {
      +  302  
                       try {
      -  302  2
                           cin.close();
      -  303  0
                       } catch (IOException ex) {
      -  304  0
                           LOGGER.trace("ignore", ex);
      -  305  2
                       }
      -  306   +  303  4
                           cin.close();
      +  304  0
                       } catch (IOException ex) {
      +  305  0
                           LOGGER.trace("ignore", ex);
      +  306  4
                       }
      +  307  
                   }
      -  307  2
                   if (out != null) {
      -  308   +  308  4
                   if (out != null) {
      +  309  
                       try {
      -  309  2
                           out.close();
      -  310  0
                       } catch (IOException ex) {
      -  311  0
                           LOGGER.trace("ignore", ex);
      -  312  2
                       }
      -  313   -
                   }
      -  314  2
                   if (gzip.isFile()) {
      -  315  2
                       FileUtils.deleteQuietly(gzip);
      -  316   +  310  4
                           out.close();
      +  311  0
                       } catch (IOException ex) {
      +  312  0
                           LOGGER.trace("ignore", ex);
      +  313  4
                       }
      +  314  
                   }
      +  315  4
                   if (gzip.isFile()) {
      +  316  4
                       FileUtils.deleteQuietly(gzip);
       317   +
                   }
      +  318  
               }
      -  318  2
           }
      -  319   +  319  4
           }
      +  320  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html index 47ab35a74..013b34797 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      NvdCve12Handler
      94%
      50/53
      82%
      28/34
      2.8
      NvdCve12Handler
      94%
      49/52
      82%
      28/34
      2.8
      NvdCve12Handler$Element
      77%
      7/9
      N/A
      2.8
      @@ -90,7 +90,7 @@
        * @author Jeremy Long
       36  
        */
      -  37  1
       public class NvdCve12Handler extends DefaultHandler {
      +  37  4
       public class NvdCve12Handler extends DefaultHandler {
       38  
       
       39   @@ -139,21 +139,21 @@
            * if the nvd cve should be skipped because it was rejected.
       61  
            */
      -  62  1
           private boolean skip = false;
      +  62  4
           private boolean skip = false;
       63  
           /**
       64  
            * flag indicating if there is a previous version.
       65  
            */
      -  66  1
           private boolean hasPreviousVersion = false;
      +  66  4
           private boolean hasPreviousVersion = false;
       67  
           /**
       68  
            * The current element.
       69  
            */
      -  70  1
           private final Element current = new Element();
      +  70  4
           private final Element current = new Element();
       71  
           /**
       72   @@ -176,7 +176,7 @@
            */
       81  
           public Map<String, List<VulnerableSoftware>> getVulnerabilities() {
      -  82  1
               return vulnerabilities;
      +  82  4
               return vulnerabilities;
       83  
           }
       84   @@ -185,31 +185,31 @@
           @Override
       86  
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      -  87  1222
               current.setNode(qName);
      -  88  1222
               if (current.isEntryNode()) {
      -  89  27
                   vendor = null;
      -  90  27
                   product = null;
      -  91  27
                   hasPreviousVersion = false;
      -  92  27
                   final String reject = attributes.getValue("reject");
      -  93  27
                   skip = "1".equals(reject);
      -  94  27
                   if (!skip) {
      -  95  26
                       vulnerability = attributes.getValue("name");
      -  96  26
                       software = new ArrayList<VulnerableSoftware>();
      +  87  2538
               current.setNode(qName);
      +  88  2538
               if (current.isEntryNode()) {
      +  89  56
                   vendor = null;
      +  90  56
                   product = null;
      +  91  56
                   hasPreviousVersion = false;
      +  92  56
                   final String reject = attributes.getValue("reject");
      +  93  56
                   skip = "1".equals(reject);
      +  94  56
                   if (!skip) {
      +  95  54
                       vulnerability = attributes.getValue("name");
      +  96  54
                       software = new ArrayList<VulnerableSoftware>();
       97  
                   } else {
      -  98  1
                       vulnerability = null;
      -  99  1
                       software = null;
      +  98  2
                       vulnerability = null;
      +  99  2
                       software = null;
       100  
                   }
      -  101  27
               } else if (!skip && current.isProdNode()) {
      -  102  52
                   vendor = attributes.getValue("vendor");
      -  103  52
                   product = attributes.getValue("name");
      -  104  1143
               } else if (!skip && current.isVersNode()) {
      -  105  761
                   final String prev = attributes.getValue("prev");
      -  106  761
                   if (prev != null && "1".equals(prev)) {
      -  107  1
                       hasPreviousVersion = true;
      -  108  1
                       final String edition = attributes.getValue("edition");
      -  109  1
                       final String num = attributes.getValue("num");
      +  101  56
               } else if (!skip && current.isProdNode()) {
      +  102  106
                   vendor = attributes.getValue("vendor");
      +  103  106
                   product = attributes.getValue("name");
      +  104  2376
               } else if (!skip && current.isVersNode()) {
      +  105  1584
                   final String prev = attributes.getValue("prev");
      +  106  1584
                   if (prev != null && "1".equals(prev)) {
      +  107  4
                       hasPreviousVersion = true;
      +  108  4
                       final String edition = attributes.getValue("edition");
      +  109  4
                       final String num = attributes.getValue("num");
       110  
       
       111   @@ -218,52 +218,52 @@
                        purposes this is good enough as we won't use this if we don't find a corresponding "a"
       113  
                        in the nvd cve 2.0. */
      -  114  1
                       final int cpeLen = 8 + vendor.length() + product.length()
      -  115  1
                           + (null != num ? (1 + num.length()) : 0)
      +  114  4
                       final int cpeLen = 8 + vendor.length() + product.length()
      +  115  4
                           + (null != num ? (1 + num.length()) : 0)
       116  0
                           + (null != edition ? (1 + edition.length()) : 0);
      -  117  1
                       final StringBuilder cpe = new StringBuilder(cpeLen);
      -  118  1
                       cpe.append("cpe:/a:").append(vendor).append(':').append(product);
      -  119  1
                       if (num != null) {
      -  120  1
                           cpe.append(':').append(num);
      +  117  4
                       final StringBuilder cpe = new StringBuilder(cpeLen);
      +  118  4
                       cpe.append("cpe:/a:").append(vendor).append(':').append(product);
      +  119  4
                       if (num != null) {
      +  120  4
                           cpe.append(':').append(num);
       121  
                       }
      -  122  1
                       if (edition != null) {
      +  122  4
                       if (edition != null) {
       123  0
                           cpe.append(':').append(edition);
       124  
                       }
      -  125  1
                       final VulnerableSoftware vs = new VulnerableSoftware();
      -  126  1
                       vs.setCpe(cpe.toString());
      -  127  1
                       vs.setPreviousVersion(prev);
      -  128  1
                       software.add(vs);
      +  125  4
                       final VulnerableSoftware vs = new VulnerableSoftware();
      +  126  4
                       vs.setCpe(cpe.toString());
      +  127  4
                       vs.setPreviousVersion(prev);
      +  128  4
                       software.add(vs);
       129  
                   }
      -  130  761
               } else if (current.isNVDNode()) {
      -  131  1
                   final String nvdVer = attributes.getValue("nvd_xml_version");
      -  132  1
                   if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
      +  130  1584
               } else if (current.isNVDNode()) {
      +  131  4
                   final String nvdVer = attributes.getValue("nvd_xml_version");
      +  132  4
                   if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
       133  0
                       throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
       134  
                   }
      -  135  1
                   vulnerabilities = new HashMap<String, List<VulnerableSoftware>>();
      +  135  4
                   vulnerabilities = new HashMap<String, List<VulnerableSoftware>>();
       136  
               }
      -  137  1222
           }
      +  137  2538
           }
       138  
       
       139  
           @Override
       140  
           public void endElement(String uri, String localName, String qName) throws SAXException {
      -  141  1222
               current.setNode(qName);
      -  142  1222
               if (current.isEntryNode()) {
      -  143  27
                   if (!skip && hasPreviousVersion) {
      -  144  1
                       vulnerabilities.put(vulnerability, software);
      +  141  2538
               current.setNode(qName);
      +  142  2538
               if (current.isEntryNode()) {
      +  143  56
                   if (!skip && hasPreviousVersion) {
      +  144  4
                       vulnerabilities.put(vulnerability, software);
       145  
                   }
      -  146  27
                   vulnerability = null;
      -  147  27
                   software = null;
      +  146  56
                   vulnerability = null;
      +  147  56
                   software = null;
       148  
               }
      -  149  1222
           }
      +  149  2538
           }
       150  
       
       151   @@ -274,7 +274,7 @@
            * A simple class to maintain information about the current element while parsing the NVD CVE XML.
       154  
            */
      -  155  1
           protected static class Element {
      +  155  4
           protected static class Element {
       156  
       
       157   @@ -356,8 +356,8 @@
                */
       196  
               public void setNode(String node) {
      -  197  2444
                   this.node = node;
      -  198  2444
               }
      +  197  5076
                   this.node = node;
      +  198  5076
               }
       199  
       
       200   @@ -372,7 +372,7 @@
                */
       205  
               public boolean isNVDNode() {
      -  206  382
                   return NVD.equals(node);
      +  206  792
                   return NVD.equals(node);
       207  
               }
       208   @@ -389,7 +389,7 @@
                */
       214  
               public boolean isEntryNode() {
      -  215  2444
                   return ENTRY.equals(node);
      +  215  5076
                   return ENTRY.equals(node);
       216  
               }
       217   @@ -423,7 +423,7 @@
                */
       232  
               public boolean isProdNode() {
      -  233  1192
                   return PROD.equals(node);
      +  233  2476
                   return PROD.equals(node);
       234  
               }
       235   @@ -440,7 +440,7 @@
                */
       241  
               public boolean isVersNode() {
      -  242  1140
                   return VERS.equals(node);
      +  242  2370
                   return VERS.equals(node);
       243  
               }
       244   @@ -451,6 +451,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html index 5f459ece4..3e4086eae 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      NvdCve20Handler
      80%
      100/125
      89%
      75/84
      3.04
      NvdCve20Handler
      87%
      108/123
      93%
      80/86
      3.04
      NvdCve20Handler$Element
      94%
      18/19
      N/A
      3.04
      @@ -98,7 +98,7 @@
        * @author Jeremy Long
       40  
        */
      -  41  1
       public class NvdCve20Handler extends DefaultHandler {
      +  41  4
       public class NvdCve20Handler extends DefaultHandler {
       42  
       
       43   @@ -107,7 +107,7 @@
            * The logger.
       45  
            */
      -  46  1
           private static final Logger LOGGER = LoggerFactory.getLogger(NvdCve20Handler.class);
      +  46  2
           private static final Logger LOGGER = LoggerFactory.getLogger(NvdCve20Handler.class);
       47  
           /**
       48   @@ -122,7 +122,7 @@
            * the current element.
       53  
            */
      -  54  1
           private final Element current = new Element();
      +  54  4
           private final Element current = new Element();
       55  
           /**
       56   @@ -153,7 +153,7 @@
            * flag indicating whether the application has a cpe.
       69  
            */
      -  70  1
           private boolean hasApplicationCpe = false;
      +  70  4
           private boolean hasApplicationCpe = false;
       71  
           /**
       72   @@ -176,7 +176,7 @@
            */
       81  
           public int getTotalNumberOfEntries() {
      -  82  0
               return totalNumberOfEntries;
      +  82  2
               return totalNumberOfEntries;
       83  
           }
       84   @@ -210,144 +210,144 @@
           @Override
       99  
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      -  100  2412
               current.setNode(qName);
      -  101  2412
               if (current.isEntryNode()) {
      -  102  27
                   hasApplicationCpe = false;
      -  103  27
                   vulnerability = new Vulnerability();
      -  104  27
                   vulnerability.setName(attributes.getValue("id"));
      -  105  2385
               } else if (current.isVulnProductNode()) {
      -  106  727
                   nodeText = new StringBuilder(100);
      -  107  1658
               } else if (current.isVulnReferencesNode()) {
      -  108  90
                   final String lang = attributes.getValue("xml:lang");
      -  109  90
                   if ("en".equals(lang)) {
      -  110  90
                       reference = new Reference();
      +  100  5020
               current.setNode(qName);
      +  101  5020
               if (current.isEntryNode()) {
      +  102  56
                   hasApplicationCpe = false;
      +  103  56
                   vulnerability = new Vulnerability();
      +  104  56
                   vulnerability.setName(attributes.getValue("id"));
      +  105  4964
               } else if (current.isVulnProductNode()) {
      +  106  1516
                   nodeText = new StringBuilder(100);
      +  107  3448
               } else if (current.isVulnReferencesNode()) {
      +  108  190
                   final String lang = attributes.getValue("xml:lang");
      +  109  190
                   if ("en".equals(lang)) {
      +  110  190
                       reference = new Reference();
       111  
                   } else {
       112  0
                       reference = null;
       113  
                   }
      -  114  90
               } else if (reference != null && current.isVulnReferenceNode()) {
      -  115  90
                   reference.setUrl(attributes.getValue("href"));
      -  116  90
                   nodeText = new StringBuilder(130);
      -  117  1478
               } else if (reference != null && current.isVulnSourceNode()) {
      -  118  90
                   nodeText = new StringBuilder(30);
      -  119  1388
               } else if (current.isVulnSummaryNode()) {
      -  120  27
                   nodeText = new StringBuilder(500);
      -  121  1361
               } else if (current.isNVDNode()) {
      -  122  1
                   final String nvdVer = attributes.getValue("nvd_xml_version");
      -  123  1
                   if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
      +  114  190
               } else if (reference != null && current.isVulnReferenceNode()) {
      +  115  190
                   reference.setUrl(attributes.getValue("href"));
      +  116  190
                   nodeText = new StringBuilder(130);
      +  117  3068
               } else if (reference != null && current.isVulnSourceNode()) {
      +  118  190
                   nodeText = new StringBuilder(30);
      +  119  2878
               } else if (current.isVulnSummaryNode()) {
      +  120  56
                   nodeText = new StringBuilder(500);
      +  121  2822
               } else if (current.isNVDNode()) {
      +  122  4
                   final String nvdVer = attributes.getValue("nvd_xml_version");
      +  123  4
                   if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
       124  0
                       throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
       125  
                   }
      -  126  1
               } else if (current.isVulnCWENode()) {
      -  127  19
                   vulnerability.setCwe(attributes.getValue("id"));
      -  128  1341
               } else if (current.isCVSSScoreNode()) {
      -  129  26
                   nodeText = new StringBuilder(5);
      -  130  1315
               } else if (current.isCVSSAccessVectorNode()) {
      -  131  26
                   nodeText = new StringBuilder(20);
      -  132  1289
               } else if (current.isCVSSAccessComplexityNode()) {
      -  133  26
                   nodeText = new StringBuilder(20);
      -  134  1263
               } else if (current.isCVSSAuthenticationNode()) {
      -  135  26
                   nodeText = new StringBuilder(20);
      -  136  1237
               } else if (current.isCVSSAvailabilityImpactNode()) {
      -  137  26
                   nodeText = new StringBuilder(20);
      -  138  1211
               } else if (current.isCVSSConfidentialityImpactNode()) {
      -  139  26
                   nodeText = new StringBuilder(20);
      -  140  1185
               } else if (current.isCVSSIntegrityImpactNode()) {
      -  141  26
                   nodeText = new StringBuilder(20);
      +  126  4
               } else if (current.isVulnCWENode()) {
      +  127  40
                   vulnerability.setCwe(attributes.getValue("id"));
      +  128  2778
               } else if (current.isCVSSScoreNode()) {
      +  129  54
                   nodeText = new StringBuilder(5);
      +  130  2724
               } else if (current.isCVSSAccessVectorNode()) {
      +  131  54
                   nodeText = new StringBuilder(20);
      +  132  2670
               } else if (current.isCVSSAccessComplexityNode()) {
      +  133  54
                   nodeText = new StringBuilder(20);
      +  134  2616
               } else if (current.isCVSSAuthenticationNode()) {
      +  135  54
                   nodeText = new StringBuilder(20);
      +  136  2562
               } else if (current.isCVSSAvailabilityImpactNode()) {
      +  137  54
                   nodeText = new StringBuilder(20);
      +  138  2508
               } else if (current.isCVSSConfidentialityImpactNode()) {
      +  139  54
                   nodeText = new StringBuilder(20);
      +  140  2454
               } else if (current.isCVSSIntegrityImpactNode()) {
      +  141  54
                   nodeText = new StringBuilder(20);
       142  
               }
      -  143  2412
           }
      +  143  5020
           }
       144  
       
       145  
           @Override
       146  
           public void characters(char[] ch, int start, int length) throws SAXException {
      -  147  3987
               if (nodeText != null) {
      -  148  1142
                   nodeText.append(ch, start, length);
      +  147  8310
               if (nodeText != null) {
      +  148  2384
                   nodeText.append(ch, start, length);
       149  
               }
      -  150  3987
           }
      +  150  8310
           }
       151  
       
       152  
           @Override
       153  
           public void endElement(String uri, String localName, String qName) throws SAXException {
      -  154  2412
               current.setNode(qName);
      -  155  2412
               if (current.isEntryNode()) {
      -  156  27
                   totalNumberOfEntries += 1;
      -  157  27
                   if (hasApplicationCpe) {
      -  158  19
                       totalNumberOfApplicationEntries += 1;
      +  154  5020
               current.setNode(qName);
      +  155  5020
               if (current.isEntryNode()) {
      +  156  56
                   totalNumberOfEntries += 1;
      +  157  56
                   if (hasApplicationCpe) {
      +  158  40
                       totalNumberOfApplicationEntries += 1;
       159  
                       try {
      -  160  19
                           saveEntry(vulnerability);
      +  160  40
                           saveEntry(vulnerability);
       161  0
                       } catch (DatabaseException ex) {
       162  0
                           throw new SAXException(ex);
       163  0
                       } catch (CorruptIndexException ex) {
       164  0
                           throw new SAXException(ex);
       165  0
                       } catch (IOException ex) {
       166  0
                           throw new SAXException(ex);
      -  167  19
                       }
      +  167  40
                       }
       168  
                   }
      -  169  27
                   vulnerability = null;
      -  170  2385
               } else if (current.isCVSSScoreNode()) {
      +  169  56
                   vulnerability = null;
      +  170  4964
               } else if (current.isCVSSScoreNode()) {
       171  
                   try {
      -  172  26
                       final float score = Float.parseFloat(nodeText.toString());
      -  173  26
                       vulnerability.setCvssScore(score);
      +  172  54
                       final float score = Float.parseFloat(nodeText.toString());
      +  173  54
                       vulnerability.setCvssScore(score);
       174  0
                   } catch (NumberFormatException ex) {
       175  0
                       LOGGER.error("Error parsing CVSS Score.");
       176  0
                       LOGGER.debug("", ex);
      -  177  26
                   }
      -  178  26
                   nodeText = null;
      -  179  2359
               } else if (current.isCVSSAccessVectorNode()) {
      -  180  26
                   vulnerability.setCvssAccessVector(nodeText.toString());
      -  181  26
                   nodeText = null;
      -  182  2333
               } else if (current.isCVSSAccessComplexityNode()) {
      -  183  26
                   vulnerability.setCvssAccessComplexity(nodeText.toString());
      -  184  26
                   nodeText = null;
      -  185  2307
               } else if (current.isCVSSAuthenticationNode()) {
      -  186  26
                   vulnerability.setCvssAuthentication(nodeText.toString());
      -  187  26
                   nodeText = null;
      -  188  2281
               } else if (current.isCVSSAvailabilityImpactNode()) {
      -  189  26
                   vulnerability.setCvssAvailabilityImpact(nodeText.toString());
      -  190  26
                   nodeText = null;
      -  191  2255
               } else if (current.isCVSSConfidentialityImpactNode()) {
      -  192  26
                   vulnerability.setCvssConfidentialityImpact(nodeText.toString());
      -  193  26
                   nodeText = null;
      -  194  2229
               } else if (current.isCVSSIntegrityImpactNode()) {
      -  195  26
                   vulnerability.setCvssIntegrityImpact(nodeText.toString());
      -  196  26
                   nodeText = null;
      -  197  2203
               } else if (current.isVulnProductNode()) {
      -  198  727
                   final String cpe = nodeText.toString();
      -  199  727
                   if (cpe.startsWith("cpe:/a:")) {
      -  200  614
                       hasApplicationCpe = true;
      -  201  614
                       vulnerability.addVulnerableSoftware(cpe);
      +  177  54
                   }
      +  178  54
                   nodeText = null;
      +  179  4910
               } else if (current.isCVSSAccessVectorNode()) {
      +  180  54
                   vulnerability.setCvssAccessVector(nodeText.toString());
      +  181  54
                   nodeText = null;
      +  182  4856
               } else if (current.isCVSSAccessComplexityNode()) {
      +  183  54
                   vulnerability.setCvssAccessComplexity(nodeText.toString());
      +  184  54
                   nodeText = null;
      +  185  4802
               } else if (current.isCVSSAuthenticationNode()) {
      +  186  54
                   vulnerability.setCvssAuthentication(nodeText.toString());
      +  187  54
                   nodeText = null;
      +  188  4748
               } else if (current.isCVSSAvailabilityImpactNode()) {
      +  189  54
                   vulnerability.setCvssAvailabilityImpact(nodeText.toString());
      +  190  54
                   nodeText = null;
      +  191  4694
               } else if (current.isCVSSConfidentialityImpactNode()) {
      +  192  54
                   vulnerability.setCvssConfidentialityImpact(nodeText.toString());
      +  193  54
                   nodeText = null;
      +  194  4640
               } else if (current.isCVSSIntegrityImpactNode()) {
      +  195  54
                   vulnerability.setCvssIntegrityImpact(nodeText.toString());
      +  196  54
                   nodeText = null;
      +  197  4586
               } else if (current.isVulnProductNode()) {
      +  198  1516
                   final String cpe = nodeText.toString();
      +  199  1516
                   if (cpe.startsWith("cpe:/a:")) {
      +  200  1290
                       hasApplicationCpe = true;
      +  201  1290
                       vulnerability.addVulnerableSoftware(cpe);
       202  
                   }
      -  203  727
                   nodeText = null;
      -  204  727
               } else if (reference != null && current.isVulnReferencesNode()) {
      -  205  90
                   vulnerability.addReference(reference);
      -  206  90
                   reference = null;
      -  207  1386
               } else if (reference != null && current.isVulnReferenceNode()) {
      -  208  90
                   reference.setName(nodeText.toString());
      -  209  90
                   nodeText = null;
      -  210  1296
               } else if (reference != null && current.isVulnSourceNode()) {
      -  211  90
                   reference.setSource(nodeText.toString());
      -  212  90
                   nodeText = null;
      -  213  1206
               } else if (current.isVulnSummaryNode()) {
      -  214  27
                   vulnerability.setDescription(nodeText.toString());
      -  215  27
                   if (nodeText.indexOf("** REJECT **") >= 0) {
      -  216  1
                       hasApplicationCpe = true; //ensure we process this to delete the vuln
      +  203  1516
                   nodeText = null;
      +  204  1516
               } else if (reference != null && current.isVulnReferencesNode()) {
      +  205  190
                   vulnerability.addReference(reference);
      +  206  190
                   reference = null;
      +  207  2880
               } else if (reference != null && current.isVulnReferenceNode()) {
      +  208  190
                   reference.setName(nodeText.toString());
      +  209  190
                   nodeText = null;
      +  210  2690
               } else if (reference != null && current.isVulnSourceNode()) {
      +  211  190
                   reference.setSource(nodeText.toString());
      +  212  190
                   nodeText = null;
      +  213  2500
               } else if (current.isVulnSummaryNode()) {
      +  214  56
                   vulnerability.setDescription(nodeText.toString());
      +  215  56
                   if (nodeText.indexOf("** REJECT **") >= 0) {
      +  216  2
                       hasApplicationCpe = true; //ensure we process this to delete the vuln
       217  
                   }
      -  218  27
                   nodeText = null;
      +  218  56
                   nodeText = null;
       219  
               }
      -  220  2412
           }
      +  220  5020
           }
       221  
           /**
       222   @@ -394,8 +394,8 @@
            */
       244  
           public void setPrevVersionVulnMap(Map<String, List<VulnerableSoftware>> map) {
      -  245  0
               prevVersionVulnMap = map;
      -  246  0
           }
      +  245  2
               prevVersionVulnMap = map;
      +  246  2
           }
       247  
       
       248   @@ -416,457 +416,456 @@
            */
       256  
           private void saveEntry(Vulnerability vuln) throws DatabaseException, CorruptIndexException, IOException {
      -  257  19
               if (cveDB == null) {
      -  258  19
                   return;
      -  259   +  257  40
               final String cveName = vuln.getName();
      +  258  40
               if (prevVersionVulnMap != null && prevVersionVulnMap.containsKey(cveName)) {
      +  259  2
                   final List<VulnerableSoftware> vulnSoftware = prevVersionVulnMap.get(cveName);
      +  260  2
                   for (VulnerableSoftware vs : vulnSoftware) {
      +  261  2
                       vuln.updateVulnerableSoftware(vs);
      +  262  2
                   }
      +  263  
               }
      -  260  0
               final String cveName = vuln.getName();
      -  261  0
               if (prevVersionVulnMap.containsKey(cveName)) {
      -  262  0
                   final List<VulnerableSoftware> vulnSoftware = prevVersionVulnMap.get(cveName);
      -  263  0
                   for (VulnerableSoftware vs : vulnSoftware) {
      -  264  0
                       vuln.updateVulnerableSoftware(vs);
      -  265  0
                   }
      +  264  40
               if (cveDB != null) {
      +  265  0
                   cveDB.updateVulnerability(vuln);
       266  
               }
      -  267  0
               cveDB.updateVulnerability(vuln);
      -  268  0
           }
      +  267  40
           }
      +  268   +
       
       269   -
       
      -  270  
           // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
      -  271   +  270  
           /**
      -  272   +  271  
            * A simple class to maintain information about the current element while parsing the NVD CVE XML.
      -  273   +  272  
            */
      -  274  1
           protected static class Element {
      +  273  4
           protected static class Element {
      +  274   +
       
       275   -
       
      +
               /**
       276   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       277   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       278   -
                */
      -  279  
               public static final String NVD = "nvd";
      +  279   +
               /**
       280   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       281   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       282   -
                */
      -  283  
               public static final String ENTRY = "entry";
      +  283   +
               /**
       284   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       285   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       286   -
                */
      -  287  
               public static final String VULN_PRODUCT = "vuln:product";
      +  287   +
               /**
       288   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       289   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       290   -
                */
      -  291  
               public static final String VULN_REFERENCES = "vuln:references";
      +  291   +
               /**
       292   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       293   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       294   -
                */
      -  295  
               public static final String VULN_SOURCE = "vuln:source";
      +  295   +
               /**
       296   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       297   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       298   -
                */
      -  299  
               public static final String VULN_REFERENCE = "vuln:reference";
      +  299   +
               /**
       300   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       301   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       302   -
                */
      -  303  
               public static final String VULN_SUMMARY = "vuln:summary";
      +  303   +
               /**
       304   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       305   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       306   -
                */
      -  307  
               public static final String VULN_CWE = "vuln:cwe";
      +  307   +
               /**
       308   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       309   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       310   -
                */
      -  311  
               public static final String CVSS_SCORE = "cvss:score";
      +  311   +
               /**
       312   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       313   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       314   -
                */
      -  315  
               public static final String CVSS_ACCESS_VECTOR = "cvss:access-vector";
      +  315   +
               /**
       316   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       317   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       318   -
                */
      -  319  
               public static final String CVSS_ACCESS_COMPLEXITY = "cvss:access-complexity";
      +  319   +
               /**
       320   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       321   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       322   -
                */
      -  323  
               public static final String CVSS_AUTHENTICATION = "cvss:authentication";
      +  323   +
               /**
       324   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       325   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       326   -
                */
      -  327  
               public static final String CVSS_CONFIDENTIALITY_IMPACT = "cvss:confidentiality-impact";
      +  327   +
               /**
       328   -
               /**
      +
                * A node type in the NVD CVE Schema 2.0
       329   -
                * A node type in the NVD CVE Schema 2.0
      +
                */
       330   -
                */
      -  331  
               public static final String CVSS_INTEGRITY_IMPACT = "cvss:integrity-impact";
      +  331   +
               /**
       332   -
               /**
      -  333  
                * A node type in the NVD CVE Schema 2.0
      +  333   +
                */
       334   -
                */
      -  335  
               public static final String CVSS_AVAILABILITY_IMPACT = "cvss:availability-impact";
      +  335   +
               /**
       336   -
               /**
      -  337  
                * The current node.
      +  337   +
                */
       338   -
                */
      -  339  
               private String node;
      +  339   +
       
       340   -
       
      +
               /**
       341   -
               /**
      -  342  
                * Gets the value of node.
      +  342   +
                *
       343   -
                *
      -  344  
                * @return the value of node
      +  344   +
                */
       345   -
                */
      -  346  
               public String getNode() {
      -  347  0
                   return this.node;
      +  346  0
                   return this.node;
      +  347   +
               }
       348   -
               }
      +
       
       349   -
       
      +
               /**
       350   -
               /**
      -  351  
                * Sets the value of node.
      +  351   +
                *
       352   -
                *
      -  353  
                * @param node new value of node
      +  353   +
                */
       354   -
                */
      -  355  
               public void setNode(String node) {
      -  356  4824
                   this.node = node;
      -  357  4824
               }
      +  355  10040
                   this.node = node;
      +  356  10040
               }
      +  357   +
       
       358   -
       
      +
               /**
       359   -
               /**
      -  360  
                * Checks if the handler is at the NVD node.
      +  360   +
                *
       361   -
                *
      +
                * @return true or false
       362   -
                * @return true or false
      +
                */
       363   -
                */
      -  364  
               public boolean isNVDNode() {
      -  365  1361
                   return NVD.equals(node);
      +  364  2822
                   return NVD.equals(node);
      +  365   +
               }
       366   -
               }
      +
       
       367   -
       
      +
               /**
       368   -
               /**
      -  369  
                * Checks if the handler is at the ENTRY node.
      +  369   +
                *
       370   -
                *
      +
                * @return true or false
       371   -
                * @return true or false
      +
                */
       372   -
                */
      -  373  
               public boolean isEntryNode() {
      -  374  4824
                   return ENTRY.equals(node);
      +  373  10040
                   return ENTRY.equals(node);
      +  374   +
               }
       375   -
               }
      +
       
       376   -
       
      +
               /**
       377   -
               /**
      -  378  
                * Checks if the handler is at the VULN_PRODUCT node.
      +  378   +
                *
       379   -
                *
      +
                * @return true or false
       380   -
                * @return true or false
      +
                */
       381   -
                */
      -  382  
               public boolean isVulnProductNode() {
      -  383  4588
                   return VULN_PRODUCT.equals(node);
      +  382  9550
                   return VULN_PRODUCT.equals(node);
      +  383   +
               }
       384   -
               }
      +
       
       385   -
       
      +
               /**
       386   -
               /**
      -  387  
                * Checks if the handler is at the REFERENCES node.
      +  387   +
                *
       388   -
                *
      +
                * @return true or false
       389   -
                * @return true or false
      +
                */
       390   -
                */
      -  391  
               public boolean isVulnReferencesNode() {
      -  392  1928
                   return VULN_REFERENCES.equals(node);
      +  391  4018
                   return VULN_REFERENCES.equals(node);
      +  392   +
               }
       393   -
               }
      +
       
       394   -
       
      +
               /**
       395   -
               /**
      -  396  
                * Checks if the handler is at the REFERENCE node.
      +  396   +
                *
       397   -
                *
      +
                * @return true or false
       398   -
                * @return true or false
      +
                */
       399   -
                */
      -  400  
               public boolean isVulnReferenceNode() {
      -  401  360
                   return VULN_REFERENCE.equals(node);
      +  400  760
                   return VULN_REFERENCE.equals(node);
      +  401   +
               }
       402   -
               }
      +
       
       403   -
       
      +
               /**
       404   -
               /**
      -  405  
                * Checks if the handler is at the VULN_SOURCE node.
      +  405   +
                *
       406   -
                *
      +
                * @return true or false
       407   -
                * @return true or false
      +
                */
       408   -
                */
      -  409  
               public boolean isVulnSourceNode() {
      -  410  180
                   return VULN_SOURCE.equals(node);
      +  409  380
                   return VULN_SOURCE.equals(node);
      +  410   +
               }
       411   -
               }
      +
       
       412   -
       
      +
               /**
       413   -
               /**
      -  414  
                * Checks if the handler is at the VULN_SUMMARY node.
      +  414   +
                *
       415   -
                *
      +
                * @return true or false
       416   -
                * @return true or false
      +
                */
       417   -
                */
      -  418  
               public boolean isVulnSummaryNode() {
      -  419  2594
                   return VULN_SUMMARY.equals(node);
      +  418  5378
                   return VULN_SUMMARY.equals(node);
      +  419   +
               }
       420   -
               }
      +
       
       421   -
       
      +
               /**
       422   -
               /**
      -  423  
                * Checks if the handler is at the VULN_CWE node.
      +  423   +
                *
       424   -
                *
      +
                * @return true or false
       425   -
                * @return true or false
      +
                */
       426   -
                */
      -  427  
               public boolean isVulnCWENode() {
      -  428  1360
                   return VULN_CWE.equals(node);
      +  427  2818
                   return VULN_CWE.equals(node);
      +  428   +
               }
       429   -
               }
      +
       
       430   -
       
      +
               /**
       431   -
               /**
      -  432  
                * Checks if the handler is at the CVSS_SCORE node.
      +  432   +
                *
       433   -
                *
      +
                * @return true or false
       434   -
                * @return true or false
      +
                */
       435   -
                */
      -  436  
               public boolean isCVSSScoreNode() {
      -  437  3726
                   return CVSS_SCORE.equals(node);
      +  436  7742
                   return CVSS_SCORE.equals(node);
      +  437   +
               }
       438   -
               }
      +
       
       439   -
       
      +
               /**
       440   -
               /**
      -  441  
                * Checks if the handler is at the CVSS_ACCESS_VECTOR node.
      +  441   +
                *
       442   -
                *
      +
                * @return true or false
       443   -
                * @return true or false
      +
                */
       444   -
                */
      -  445  
               public boolean isCVSSAccessVectorNode() {
      -  446  3674
                   return CVSS_ACCESS_VECTOR.equals(node);
      +  445  7634
                   return CVSS_ACCESS_VECTOR.equals(node);
      +  446   +
               }
       447   -
               }
      +
       
       448   -
       
      +
               /**
       449   -
               /**
      -  450  
                * Checks if the handler is at the CVSS_ACCESS_COMPLEXITY node.
      +  450   +
                *
       451   -
                *
      +
                * @return true or false
       452   -
                * @return true or false
      +
                */
       453   -
                */
      -  454  
               public boolean isCVSSAccessComplexityNode() {
      -  455  3622
                   return CVSS_ACCESS_COMPLEXITY.equals(node);
      +  454  7526
                   return CVSS_ACCESS_COMPLEXITY.equals(node);
      +  455   +
               }
       456   -
               }
      +
       
       457   -
       
      +
               /**
       458   -
               /**
      -  459  
                * Checks if the handler is at the CVSS_AUTHENTICATION node.
      +  459   +
                *
       460   -
                *
      +
                * @return true or false
       461   -
                * @return true or false
      +
                */
       462   -
                */
      -  463  
               public boolean isCVSSAuthenticationNode() {
      -  464  3570
                   return CVSS_AUTHENTICATION.equals(node);
      +  463  7418
                   return CVSS_AUTHENTICATION.equals(node);
      +  464   +
               }
       465   -
               }
      +
       
       466   -
       
      +
               /**
       467   -
               /**
      -  468  
                * Checks if the handler is at the CVSS_CONFIDENTIALITY_IMPACT node.
      +  468   +
                *
       469   -
                *
      +
                * @return true or false
       470   -
                * @return true or false
      +
                */
       471   -
                */
      -  472  
               public boolean isCVSSConfidentialityImpactNode() {
      -  473  3466
                   return CVSS_CONFIDENTIALITY_IMPACT.equals(node);
      +  472  7202
                   return CVSS_CONFIDENTIALITY_IMPACT.equals(node);
      +  473   +
               }
       474   -
               }
      +
       
       475   -
       
      +
               /**
       476   -
               /**
      -  477  
                * Checks if the handler is at the CVSS_INTEGRITY_IMPACT node.
      +  477   +
                *
       478   -
                *
      +
                * @return true or false
       479   -
                * @return true or false
      +
                */
       480   -
                */
      -  481  
               public boolean isCVSSIntegrityImpactNode() {
      -  482  3414
                   return CVSS_INTEGRITY_IMPACT.equals(node);
      +  481  7094
                   return CVSS_INTEGRITY_IMPACT.equals(node);
      +  482   +
               }
       483   -
               }
      -  484  
       
      -  485   +  484  
               /**
      -  486   +  485  
                * Checks if the handler is at the CVSS_AVAILABILITY_IMPACT node.
      -  487   +  486  
                *
      -  488   +  487  
                * @return true or false
      -  489   +  488  
                */
      -  490   +  489  
               public boolean isCVSSAvailabilityImpactNode() {
      -  491  3518
                   return CVSS_AVAILABILITY_IMPACT.equals(node);
      -  492   +  490  7310
                   return CVSS_AVAILABILITY_IMPACT.equals(node);
      +  491  
               }
      -  493   +  492  
           }
      -  494   +  493  
           // </editor-fold>
      -  495   +  494  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html index 8008e4af5..21d437ce6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html @@ -65,7 +65,7 @@
        * @author Jeremy Long
       24  
        */
      -  25  15
       public class NvdCveInfo {
      +  25  30
       public class NvdCveInfo {
       26  
       
       27   @@ -90,7 +90,7 @@
            */
       37  
           public String getId() {
      -  38  10
               return id;
      +  38  20
               return id;
       39  
           }
       40   @@ -107,8 +107,8 @@
            */
       46  
           public void setId(String id) {
      -  47  11
               this.id = id;
      -  48  11
           }
      +  47  22
               this.id = id;
      +  48  22
           }
       49  
           /**
       50   @@ -131,7 +131,7 @@
            */
       59  
           public String getUrl() {
      -  60  4
               return url;
      +  60  8
               return url;
       61  
           }
       62   @@ -148,8 +148,8 @@
            */
       68  
           public void setUrl(String url) {
      -  69  11
               this.url = url;
      -  70  11
           }
      +  69  22
               this.url = url;
      +  70  22
           }
       71  
           /**
       72   @@ -172,7 +172,7 @@
            */
       81  
           public String getOldSchemaVersionUrl() {
      -  82  4
               return oldSchemaVersionUrl;
      +  82  8
               return oldSchemaVersionUrl;
       83  
           }
       84   @@ -189,8 +189,8 @@
            */
       90  
           public void setOldSchemaVersionUrl(String oldSchemaVersionUrl) {
      -  91  11
               this.oldSchemaVersionUrl = oldSchemaVersionUrl;
      -  92  11
           }
      +  91  22
               this.oldSchemaVersionUrl = oldSchemaVersionUrl;
      +  92  22
           }
       93  
           /**
       94   @@ -213,7 +213,7 @@
            */
       103  
           public long getTimestamp() {
      -  104  1
               return timestamp;
      +  104  2
               return timestamp;
       105  
           }
       106   @@ -230,15 +230,15 @@
            */
       112  
           public void setTimestamp(long timestamp) {
      -  113  10
               this.timestamp = timestamp;
      -  114  10
           }
      +  113  20
               this.timestamp = timestamp;
      +  114  20
           }
       115  
           /**
       116  
            * indicates whether or not this item should be updated.
       117  
            */
      -  118  15
           private boolean needsUpdate = true;
      +  118  30
           private boolean needsUpdate = true;
       119  
       
       120   @@ -253,7 +253,7 @@
            */
       125  
           public boolean getNeedsUpdate() {
      -  126  5
               return needsUpdate;
      +  126  10
               return needsUpdate;
       127  
           }
       128   @@ -270,12 +270,12 @@
            */
       134  
           public void setNeedsUpdate(boolean needsUpdate) {
      -  135  11
               this.needsUpdate = needsUpdate;
      -  136  11
           }
      +  135  22
               this.needsUpdate = needsUpdate;
      +  136  22
           }
       137  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html index d6fd95fde..c688ebc44 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html @@ -336,6 +336,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html index debe41825..799e72511 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html @@ -85,7 +85,7 @@
        * @author Jeremy Long
       34  
        */
      -  35  12
       public class UpdateableNvdCve implements Iterable<NvdCveInfo>, Iterator<NvdCveInfo> {
      +  35  24
       public class UpdateableNvdCve implements Iterable<NvdCveInfo>, Iterator<NvdCveInfo> {
       36  
       
       37   @@ -94,7 +94,7 @@
            * A collection of sources of data.
       39  
            */
      -  40  5
           private final Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>();
      +  40  10
           private final Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>();
       41  
       
       42   @@ -109,7 +109,7 @@
            */
       47  
           protected Map<String, NvdCveInfo> getCollection() {
      -  48  3
               return collection;
      +  48  6
               return collection;
       49  
           }
       50   @@ -126,13 +126,13 @@
            */
       56  
           public boolean isUpdateNeeded() {
      -  57  3
               for (NvdCveInfo item : this) {
      -  58  4
                   if (item.getNeedsUpdate()) {
      -  59  1
                       return true;
      +  57  6
               for (NvdCveInfo item : this) {
      +  58  8
                   if (item.getNeedsUpdate()) {
      +  59  2
                       return true;
       60  
                   }
      -  61  3
               }
      -  62  2
               return false;
      +  61  6
               }
      +  62  4
               return false;
       63  
           }
       64   @@ -157,8 +157,8 @@
            */
       74  
           public void add(String id, String url, String oldUrl) throws MalformedURLException, DownloadFailedException {
      -  75  1
               add(id, url, oldUrl, false);
      -  76  1
           }
      +  75  2
               add(id, url, oldUrl, false);
      +  76  2
           }
       77  
       
       78   @@ -183,14 +183,14 @@
            */
       88  
           public void add(String id, String url, String oldUrl, boolean needsUpdate) throws MalformedURLException, DownloadFailedException {
      -  89  9
               final NvdCveInfo item = new NvdCveInfo();
      -  90  9
               item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false.
      -  91  9
               item.setId(id);
      -  92  9
               item.setUrl(url);
      -  93  9
               item.setOldSchemaVersionUrl(oldUrl);
      -  94  9
               item.setTimestamp(Downloader.getLastModified(new URL(url)));
      -  95  9
               collection.put(id, item);
      -  96  9
           }
      +  89  18
               final NvdCveInfo item = new NvdCveInfo();
      +  90  18
               item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false.
      +  91  18
               item.setId(id);
      +  92  18
               item.setUrl(url);
      +  93  18
               item.setOldSchemaVersionUrl(oldUrl);
      +  94  18
               item.setTimestamp(Downloader.getLastModified(new URL(url)));
      +  95  18
               collection.put(id, item);
      +  96  18
           }
       97  
       
       98   @@ -201,8 +201,8 @@
            */
       101  
           public void clear() {
      -  102  1
               collection.clear();
      -  103  1
           }
      +  102  2
               collection.clear();
      +  103  2
           }
       104  
       
       105   @@ -228,7 +228,7 @@
            * An internal iterator used to implement iterable.
       116  
            */
      -  117  5
           private Iterator<Entry<String, NvdCveInfo>> iterableContent = null;
      +  117  10
           private Iterator<Entry<String, NvdCveInfo>> iterableContent = null;
       118  
       
       119   @@ -251,8 +251,8 @@
           @Override
       128  
           public Iterator<NvdCveInfo> iterator() {
      -  129  4
               iterableContent = collection.entrySet().iterator();
      -  130  4
               return this;
      +  129  8
               iterableContent = collection.entrySet().iterator();
      +  130  8
               return this;
       131  
           }
       132   @@ -277,7 +277,7 @@
           @Override
       142  
           public boolean hasNext() {
      -  143  10
               return iterableContent.hasNext();
      +  143  20
               return iterableContent.hasNext();
       144  
           }
       145   @@ -302,7 +302,7 @@
           @Override
       155  
           public NvdCveInfo next() {
      -  156  7
               return iterableContent.next().getValue();
      +  156  14
               return iterableContent.next().getValue();
       157  
           }
       158   @@ -323,8 +323,8 @@
           @Override
       166  
           public void remove() {
      -  167  1
               iterableContent.remove();
      -  168  1
           }
      +  167  2
               iterableContent.remove();
      +  168  2
           }
       169  
       
       170   @@ -341,7 +341,7 @@
            */
       176  
           public NvdCveInfo get(String key) {
      -  177  2
               return collection.get(key);
      +  177  4
               return collection.get(key);
       178  
           }
       179   @@ -357,6 +357,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Confidence.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Confidence.html index bd188791e..865487f3b 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Confidence.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Confidence.html @@ -65,7 +65,7 @@
        * @author Jeremy Long
       24  
        */
      -  25  10
       public enum Confidence {
      +  25  24
       public enum Confidence {
       26  
       
       27   @@ -74,32 +74,32 @@
            * High confidence evidence.
       29  
            */
      -  30  1
           HIGHEST,
      +  30  2
           HIGHEST,
       31  
           /**
       32  
            * High confidence evidence.
       33  
            */
      -  34  1
           HIGH,
      +  34  2
           HIGH,
       35  
           /**
       36  
            * Medium confidence evidence.
       37  
            */
      -  38  1
           MEDIUM,
      +  38  2
           MEDIUM,
       39  
           /**
       40  
            * Low confidence evidence.
       41  
            */
      -  42  1
           LOW
      +  42  2
           LOW
       43  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Dependency.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Dependency.html index 94f4d610a..9de33ead8 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Dependency.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Dependency.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      Dependency
      64%
      117/182
      47%
      17/36
      1.393
      Dependency
      64%
      122/189
      50%
      20/40
      1.414
       
      @@ -94,717 +94,717 @@  38  
       /**
       39   -
        * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about
      +
        * A program dependency. This object is one of the core components within
       40   -
        * the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published,
      +
        * DependencyCheck. It is used to collect information about the dependency in
       41   -
        * vulnerabilities associated with the program dependency.
      +
        * the form of evidence. The Evidence is then used to determine if there are any
       42   -
        *
      +
        * known, published, vulnerabilities associated with the program dependency.
       43   -
        * @author Jeremy Long
      +
        *
       44   +
        * @author Jeremy Long
      +  45  
        */
      -  45  2
       public class Dependency implements Serializable, Comparable<Dependency> {
      -  46   -
       
      +  46  4
       public class Dependency implements Serializable, Comparable<Dependency> {
       47   -
           /**
      +
       
       48   -
            * The serial version UID for serialization.
      +
           /**
       49   -
            */
      +
            * The serial version UID for serialization.
       50   -
           private static final long serialVersionUID = 1L;
      +
            */
       51   -
           /**
      +
           private static final long serialVersionUID = 1L;
       52   -
            * The logger.
      +
           /**
       53   +
            * The logger.
      +  54  
            */
      -  54  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class);
      -  55   -
           /**
      +  55  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class);
       56   -
            * Used as starting point for generating the value in {@link #hashCode()}.
      +
           /**
       57   -
            */
      +
            * Used as starting point for generating the value in {@link #hashCode()}.
       58   -
           private static final int MAGIC_HASH_INIT_VALUE = 3;
      +
            */
       59   -
           /**
      +
           private static final int MAGIC_HASH_INIT_VALUE = 3;
       60   -
            * Used as a multiplier for generating the value in {@link #hashCode()}.
      +
           /**
       61   -
            */
      +
            * Used as a multiplier for generating the value in {@link #hashCode()}.
       62   -
           private static final int MAGIC_HASH_MULTIPLIER = 47;
      +
            */
       63   -
           /**
      +
           private static final int MAGIC_HASH_MULTIPLIER = 47;
       64   -
            * The actual file path of the dependency on disk.
      +
           /**
       65   -
            */
      +
            * The actual file path of the dependency on disk.
       66   -
           private String actualFilePath;
      +
            */
       67   -
           /**
      +
           private String actualFilePath;
       68   -
            * The file path to display.
      +
           /**
       69   -
            */
      +
            * The file path to display.
       70   -
           private String filePath;
      +
            */
       71   -
           /**
      +
           private String filePath;
       72   -
            * The file name of the dependency.
      +
           /**
       73   -
            */
      +
            * The file name of the dependency.
       74   -
           private String fileName;
      +
            */
       75   -
           /**
      +
           private String fileName;
       76   -
            * The md5 hash of the dependency.
      +
       
       77   -
            */
      +
           /**
       78   -
           private String md5sum;
      +
            * The package path.
       79   -
           /**
      +
            */
       80   -
            * The SHA1 hash of the dependency.
      +
           private String packagePath;
       81   -
            */
      +
       
       82   -
           private String sha1sum;
      +
           /**
       83   -
           /**
      +
            * Returns the package path.
       84   -
            * A list of Identifiers.
      +
            *
       85   -
            */
      +
            * @return the package path
       86   -
           private Set<Identifier> identifiers;
      -  87   -
           /**
      -  88   -
            * A collection of vendor evidence.
      -  89  
            */
      +  87   +
           public String getPackagePath() {
      +  88  0
               return packagePath;
      +  89   +
           }
       90   -
           private final EvidenceCollection vendorEvidence;
      +
       
       91  
           /**
       92   -
            * A collection of product evidence.
      +
            * Sets the package path.
       93   -
            */
      +
            *
       94   -
           private final EvidenceCollection productEvidence;
      +
            * @param packagePath the package path
       95   -
           /**
      -  96   -
            * A collection of version evidence.
      -  97  
            */
      -  98   -
           private final EvidenceCollection versionEvidence;
      +  96   +
           public void setPackagePath(String packagePath) {
      +  97  8
               this.packagePath = packagePath;
      +  98  8
           }
       99  
       
       100  
           /**
       101   -
            * Constructs a new Dependency object.
      +
            * The md5 hash of the dependency.
       102  
            */
      -  103  88
           public Dependency() {
      -  104  88
               vendorEvidence = new EvidenceCollection();
      -  105  88
               productEvidence = new EvidenceCollection();
      -  106  88
               versionEvidence = new EvidenceCollection();
      -  107  88
               identifiers = new TreeSet<Identifier>();
      -  108  88
               vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
      -  109  88
               suppressedIdentifiers = new TreeSet<Identifier>();
      -  110  88
               suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
      -  111  88
           }
      +  103   +
           private String md5sum;
      +  104   +
           /**
      +  105   +
            * The SHA1 hash of the dependency.
      +  106   +
            */
      +  107   +
           private String sha1sum;
      +  108   +
           /**
      +  109   +
            * A list of Identifiers.
      +  110   +
            */
      +  111   +
           private Set<Identifier> identifiers;
       112   -
       
      +
           /**
       113   -
           /**
      +
            * A collection of vendor evidence.
       114   -
            * Constructs a new Dependency object.
      +
            */
       115   -
            *
      +
           private final EvidenceCollection vendorEvidence;
       116   -
            * @param file the File to create the dependency object from.
      +
           /**
       117   -
            */
      +
            * A collection of product evidence.
       118   -
           public Dependency(File file) {
      -  119  67
               this();
      -  120  67
               this.actualFilePath = file.getAbsolutePath();
      -  121  67
               this.filePath = this.actualFilePath;
      -  122  67
               this.fileName = file.getName();
      -  123  67
               determineHashes(file);
      -  124  67
           }
      +
            */
      +  119   +
           private final EvidenceCollection productEvidence;
      +  120   +
           /**
      +  121   +
            * A collection of version evidence.
      +  122   +
            */
      +  123   +
           private final EvidenceCollection versionEvidence;
      +  124   +
       
       125   -
       
      +
           /**
       126   -
           /**
      +
            * Constructs a new Dependency object.
       127   -
            * Returns the file name of the dependency.
      -  128   -
            *
      -  129   -
            * @return the file name of the dependency
      -  130  
            */
      -  131   -
           public String getFileName() {
      -  132  36
               return this.fileName;
      -  133   -
           }
      -  134   -
       
      -  135   -
           /**
      -  136   -
            * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I
      +  128  184
           public Dependency() {
      +  129  184
               vendorEvidence = new EvidenceCollection();
      +  130  184
               productEvidence = new EvidenceCollection();
      +  131  184
               versionEvidence = new EvidenceCollection();
      +  132  184
               identifiers = new TreeSet<Identifier>();
      +  133  184
               vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
      +  134  184
               suppressedIdentifiers = new TreeSet<Identifier>();
      +  135  184
               suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
      +  136  184
           }
       137   -
            * could not get the replace to work in the template itself.
      +
       
       138   -
            *
      +
           /**
       139   -
            * @return the file name of the dependency with the backslash escaped for use in JavaScript
      +
            * Constructs a new Dependency object.
       140   -
            */
      +
            *
       141   -
           public String getFileNameForJavaScript() {
      -  142  0
               return this.fileName.replace("\\", "\\\\");
      +
            * @param file the File to create the dependency object from.
      +  142   +
            */
       143   -
           }
      -  144   +
           public Dependency(File file) {
      +  144  142
               this();
      +  145  142
               this.actualFilePath = file.getAbsolutePath();
      +  146  142
               this.filePath = this.actualFilePath;
      +  147  142
               this.fileName = file.getName();
      +  148  142
               this.packagePath = filePath;
      +  149  142
               determineHashes(file);
      +  150  142
           }
      +  151  
       
      -  145   +  152  
           /**
      -  146   -
            * Sets the file name of the dependency.
      -  147   -
            *
      -  148   -
            * @param fileName the file name of the dependency
      -  149   -
            */
      -  150   -
           public void setFileName(String fileName) {
      -  151  7
               this.fileName = fileName;
      -  152  7
           }
       153   -
       
      +
            * Returns the file name of the dependency.
       154   -
           /**
      +
            *
       155   -
            * Sets the actual file path of the dependency on disk.
      +
            * @return the file name of the dependency
       156   -
            *
      +
            */
       157   -
            * @param actualFilePath the file path of the dependency
      -  158   -
            */
      +
           public String getFileName() {
      +  158  98
               return this.fileName;
       159   -
           public void setActualFilePath(String actualFilePath) {
      -  160  2
               this.actualFilePath = actualFilePath;
      -  161  2
               if (this.sha1sum == null) {
      -  162  0
                   final File file = new File(this.actualFilePath);
      -  163  0
                   determineHashes(file);
      +
           }
      +  160   +
       
      +  161   +
           /**
      +  162   +
            * Returns the file name of the dependency with the backslash escaped for
      +  163   +
            * use in JavaScript. This is a complete hack as I could not get the replace
       164   -
               }
      -  165  2
           }
      +
            * to work in the template itself.
      +  165   +
            *
       166   -
       
      +
            * @return the file name of the dependency with the backslash escaped for
       167   -
           /**
      +
            * use in JavaScript
       168   -
            * Gets the file path of the dependency.
      +
            */
       169   -
            *
      -  170   -
            * @return the file path of the dependency
      +
           public String getFileNameForJavaScript() {
      +  170  0
               return this.fileName.replace("\\", "\\\\");
       171   -
            */
      +
           }
       172   -
           public String getActualFilePath() {
      -  173  51
               return this.actualFilePath;
      +
       
      +  173   +
           /**
       174   -
           }
      +
            * Sets the file name of the dependency.
       175   -
       
      +
            *
       176   -
           /**
      +
            * @param fileName the file name of the dependency
       177   -
            * Gets a reference to the File object.
      +
            */
       178   -
            *
      -  179   -
            * @return the File object
      -  180   -
            */
      +
           public void setFileName(String fileName) {
      +  179  14
               this.fileName = fileName;
      +  180  14
           }
       181   -
           public File getActualFile() {
      -  182  93
               return new File(this.actualFilePath);
      +
       
      +  182   +
           /**
       183   -
           }
      +
            * Sets the actual file path of the dependency on disk.
       184   -
       
      +
            *
       185   -
           /**
      +
            * @param actualFilePath the file path of the dependency
       186   -
            * Sets the file path of the dependency.
      +
            */
       187   -
            *
      -  188   -
            * @param filePath the file path of the dependency
      -  189   -
            */
      -  190   -
           public void setFilePath(String filePath) {
      -  191  37
               this.filePath = filePath;
      -  192  37
           }
      -  193   -
       
      -  194   -
           /**
      -  195   -
            * The file name to display in reports.
      -  196   -
            */
      -  197  88
           private String displayName = null;
      -  198   -
       
      -  199   -
           /**
      -  200   -
            * Sets the file name to display in reports.
      -  201   -
            *
      -  202   -
            * @param displayName the name to display
      -  203   -
            */
      -  204   -
           public void setDisplayFileName(String displayName) {
      -  205  47
               this.displayName = displayName;
      -  206  47
           }
      -  207   -
       
      -  208   -
           /**
      -  209   -
            * Returns the file name to display in reports; if no display file name has been set it will default to the actual file name.
      -  210   -
            *
      -  211   -
            * @return the file name to display
      -  212   -
            */
      -  213   -
           public String getDisplayFileName() {
      -  214  40
               if (displayName == null) {
      -  215  30
                   return this.fileName;
      -  216   +
           public void setActualFilePath(String actualFilePath) {
      +  188  4
               this.actualFilePath = actualFilePath;
      +  189  4
               if (this.sha1sum == null) {
      +  190  0
                   final File file = new File(this.actualFilePath);
      +  191  0
                   determineHashes(file);
      +  192  
               }
      -  217  10
               return this.displayName;
      -  218   -
           }
      -  219   +  193  4
           }
      +  194  
       
      -  220   +  195  
           /**
      -  221   -
            * <p>
      -  222   -
            * Gets the file path of the dependency.</p>
      -  223   -
            * <p>
      -  224   -
            * <b>NOTE:</b> This may not be the actual path of the file on disk. The actual path of the file on disk can be obtained via
      -  225   -
            * the getActualFilePath().</p>
      -  226   +  196   +
            * Gets the file path of the dependency.
      +  197  
            *
      -  227   +  198  
            * @return the file path of the dependency
      -  228   +  199  
            */
      +  200   +
           public String getActualFilePath() {
      +  201  148
               return this.actualFilePath;
      +  202   +
           }
      +  203   +
       
      +  204   +
           /**
      +  205   +
            * Gets a reference to the File object.
      +  206   +
            *
      +  207   +
            * @return the File object
      +  208   +
            */
      +  209   +
           public File getActualFile() {
      +  210  272
               return new File(this.actualFilePath);
      +  211   +
           }
      +  212   +
       
      +  213   +
           /**
      +  214   +
            * Sets the file path of the dependency.
      +  215   +
            *
      +  216   +
            * @param filePath the file path of the dependency
      +  217   +
            */
      +  218   +
           public void setFilePath(String filePath) {
      +  219  74
               if (this.packagePath == null || this.packagePath.equals(this.filePath)) {
      +  220  74
                   this.packagePath = filePath;
      +  221   +
               }
      +  222  74
               this.filePath = filePath;
      +  223  74
           }
      +  224   +
       
      +  225   +
           /**
      +  226   +
            * The file name to display in reports.
      +  227   +
            */
      +  228  184
           private String displayName = null;
       229   -
           public String getFilePath() {
      -  230  70
               return this.filePath;
      +
       
      +  230   +
           /**
       231   -
           }
      +
            * Sets the file name to display in reports.
       232   -
       
      +
            *
       233   -
           /**
      +
            * @param displayName the name to display
       234   -
            * Returns the MD5 Checksum of the dependency file.
      +
            */
       235   -
            *
      -  236   -
            * @return the MD5 Checksum
      -  237   -
            */
      +
           public void setDisplayFileName(String displayName) {
      +  236  94
               this.displayName = displayName;
      +  237  94
           }
       238   -
           public String getMd5sum() {
      -  239  2
               return this.md5sum;
      +
       
      +  239   +
           /**
       240   -
           }
      +
            * Returns the file name to display in reports; if no display file name has
       241   -
       
      +
            * been set it will default to the actual file name.
       242   -
           /**
      +
            *
       243   -
            * Sets the MD5 Checksum of the dependency.
      +
            * @return the file name to display
       244   -
            *
      +
            */
       245   -
            * @param md5sum the MD5 Checksum
      -  246   -
            */
      -  247   -
           public void setMd5sum(String md5sum) {
      -  248  68
               this.md5sum = md5sum;
      -  249  68
           }
      +
           public String getDisplayFileName() {
      +  246  80
               if (displayName == null) {
      +  247  60
                   return this.fileName;
      +  248   +
               }
      +  249  20
               return this.displayName;
       250   -
       
      +
           }
       251   -
           /**
      +
       
       252   -
            * Returns the SHA1 Checksum of the dependency.
      +
           /**
       253   -
            *
      +
            * <p>
       254   -
            * @return the SHA1 Checksum
      +
            * Gets the file path of the dependency.</p>
       255   -
            */
      +
            * <p>
       256   -
           public String getSha1sum() {
      -  257  9
               return this.sha1sum;
      +
            * <b>NOTE:</b> This may not be the actual path of the file on disk. The
      +  257   +
            * actual path of the file on disk can be obtained via the
       258   -
           }
      +
            * getActualFilePath().</p>
       259   -
       
      +
            *
       260   -
           /**
      +
            * @return the file path of the dependency
       261   -
            * Sets the SHA1 Checksum of the dependency.
      +
            */
       262   -
            *
      -  263   -
            * @param sha1sum the SHA1 Checksum
      +
           public String getFilePath() {
      +  263  236
               return this.filePath;
       264   -
            */
      -  265   -
           public void setSha1sum(String sha1sum) {
      -  266  106
               this.sha1sum = sha1sum;
      -  267  106
           }
      -  268   -
       
      -  269   -
           /**
      -  270   -
            * Returns a List of Identifiers.
      -  271   -
            *
      -  272   -
            * @return an ArrayList of Identifiers
      -  273   -
            */
      -  274   -
           public Set<Identifier> getIdentifiers() {
      -  275  198
               return this.identifiers;
      -  276  
           }
      +  265   +
       
      +  266   +
           /**
      +  267   +
            * Returns the MD5 Checksum of the dependency file.
      +  268   +
            *
      +  269   +
            * @return the MD5 Checksum
      +  270   +
            */
      +  271   +
           public String getMd5sum() {
      +  272  4
               return this.md5sum;
      +  273   +
           }
      +  274   +
       
      +  275   +
           /**
      +  276   +
            * Sets the MD5 Checksum of the dependency.
       277   -
       
      +
            *
       278   -
           /**
      +
            * @param md5sum the MD5 Checksum
       279   -
            * Sets a List of Identifiers.
      +
            */
       280   -
            *
      -  281   -
            * @param identifiers A list of Identifiers
      -  282   -
            */
      +
           public void setMd5sum(String md5sum) {
      +  281  144
               this.md5sum = md5sum;
      +  282  144
           }
       283   -
           public void setIdentifiers(Set<Identifier> identifiers) {
      -  284  1
               this.identifiers = identifiers;
      -  285  1
           }
      +
       
      +  284   +
           /**
      +  285   +
            * Returns the SHA1 Checksum of the dependency.
       286   -
       
      +
            *
       287   -
           /**
      +
            * @return the SHA1 Checksum
       288   -
            * Adds an entry to the list of detected Identifiers for the dependency file.
      -  289   -
            *
      -  290   -
            * @param type the type of identifier (such as CPE)
      -  291   -
            * @param value the value of the identifier
      -  292   -
            * @param url the URL of the identifier
      -  293  
            */
      -  294   -
           public void addIdentifier(String type, String value, String url) {
      -  295  11
               final Identifier i = new Identifier(type, value, url);
      -  296  11
               this.identifiers.add(i);
      -  297  11
           }
      -  298   +  289   +
           public String getSha1sum() {
      +  290  26
               return this.sha1sum;
      +  291   +
           }
      +  292  
       
      -  299   +  293  
           /**
      -  300   -
            * Adds an entry to the list of detected Identifiers for the dependency file.
      -  301   +  294   +
            * Sets the SHA1 Checksum of the dependency.
      +  295  
            *
      +  296   +
            * @param sha1sum the SHA1 Checksum
      +  297   +
            */
      +  298   +
           public void setSha1sum(String sha1sum) {
      +  299  220
               this.sha1sum = sha1sum;
      +  300  220
           }
      +  301   +
       
       302   -
            * @param type the type of identifier (such as CPE)
      +
           /**
       303   -
            * @param value the value of the identifier
      +
            * Returns a List of Identifiers.
       304   -
            * @param url the URL of the identifier
      +
            *
       305   -
            * @param confidence the confidence in the Identifier being accurate
      +
            * @return an ArrayList of Identifiers
       306  
            */
       307   -
           public void addIdentifier(String type, String value, String url, Confidence confidence) {
      -  308  2
               final Identifier i = new Identifier(type, value, url);
      -  309  2
               i.setConfidence(confidence);
      -  310  2
               this.identifiers.add(i);
      -  311  2
           }
      +
           public Set<Identifier> getIdentifiers() {
      +  308  908
               return this.identifiers;
      +  309   +
           }
      +  310   +
       
      +  311   +
           /**
       312   -
       
      +
            * Sets a List of Identifiers.
       313   -
           /**
      +
            *
       314   -
            * Adds the maven artifact as evidence.
      +
            * @param identifiers A list of Identifiers
       315   -
            *
      -  316   -
            * @param source The source of the evidence
      -  317   -
            * @param mavenArtifact The maven artifact
      -  318   -
            * @param confidence The confidence level of this evidence
      -  319  
            */
      -  320   -
           public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) {
      -  321  2
               if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) {
      -  322  1
                   this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence);
      -  323   -
               }
      -  324  2
               if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) {
      -  325  1
                   this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence);
      -  326   -
               }
      -  327  2
               if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) {
      -  328  1
                   this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence);
      -  329   -
               }
      -  330  2
               if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
      -  331  1
                   boolean found = false;
      -  332  1
                   for (Identifier i : this.getIdentifiers()) {
      -  333  0
                       if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
      -  334  0
                           found = true;
      -  335  0
                           i.setConfidence(Confidence.HIGHEST);
      -  336  0
                           final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22";
      -  337  0
                           i.setUrl(url);
      -  338   -
                           //i.setUrl(mavenArtifact.getArtifactUrl());
      -  339  0
                           LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue());
      -  340  0
                           break;
      -  341   -
                       }
      -  342  0
                   }
      -  343  1
                   if (!found) {
      -  344  1
                       LOGGER.debug("Adding new maven identifier {}", mavenArtifact);
      -  345  1
                       this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
      -  346   -
                   }
      -  347   -
               }
      -  348  2
           }
      -  349   +  316   +
           public void setIdentifiers(Set<Identifier> identifiers) {
      +  317  2
               this.identifiers = identifiers;
      +  318  2
           }
      +  319  
       
      -  350   +  320  
           /**
      -  351   -
            * Adds an entry to the list of detected Identifiers for the dependency file.
      -  352   +  321   +
            * Adds an entry to the list of detected Identifiers for the dependency
      +  322   +
            * file.
      +  323  
            *
      +  324   +
            * @param type the type of identifier (such as CPE)
      +  325   +
            * @param value the value of the identifier
      +  326   +
            * @param url the URL of the identifier
      +  327   +
            */
      +  328   +
           public void addIdentifier(String type, String value, String url) {
      +  329  22
               final Identifier i = new Identifier(type, value, url);
      +  330  22
               this.identifiers.add(i);
      +  331  22
           }
      +  332   +
       
      +  333   +
           /**
      +  334   +
            * Adds an entry to the list of detected Identifiers for the dependency
      +  335   +
            * file.
      +  336   +
            *
      +  337   +
            * @param type the type of identifier (such as CPE)
      +  338   +
            * @param value the value of the identifier
      +  339   +
            * @param url the URL of the identifier
      +  340   +
            * @param confidence the confidence in the Identifier being accurate
      +  341   +
            */
      +  342   +
           public void addIdentifier(String type, String value, String url, Confidence confidence) {
      +  343  6
               final Identifier i = new Identifier(type, value, url);
      +  344  6
               i.setConfidence(confidence);
      +  345  6
               this.identifiers.add(i);
      +  346  6
           }
      +  347   +
       
      +  348   +
           /**
      +  349   +
            * Adds the maven artifact as evidence.
      +  350   +
            *
      +  351   +
            * @param source The source of the evidence
      +  352   +
            * @param mavenArtifact The maven artifact
       353   -
            * @param identifier the identifier to add
      +
            * @param confidence The confidence level of this evidence
       354  
            */
       355   -
           public void addIdentifier(Identifier identifier) {
      -  356  3
               this.identifiers.add(identifier);
      -  357  3
           }
      +
           public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) {
      +  356  4
               if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) {
      +  357  2
                   this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence);
       358   -
       
      -  359   -
           /**
      -  360   -
            * A set of identifiers that have been suppressed.
      +
               }
      +  359  4
               if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) {
      +  360  2
                   this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence);
       361   -
            */
      -  362   -
           private Set<Identifier> suppressedIdentifiers;
      -  363   -
       
      +
               }
      +  362  4
               if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) {
      +  363  2
                   this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence);
       364   -
           /**
      -  365   -
            * Get the value of suppressedIdentifiers.
      -  366   -
            *
      -  367   -
            * @return the value of suppressedIdentifiers
      -  368   -
            */
      -  369   -
           public Set<Identifier> getSuppressedIdentifiers() {
      -  370  5
               return suppressedIdentifiers;
      -  371   -
           }
      -  372   -
       
      +
               }
      +  365  4
               if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
      +  366  2
                   boolean found = false;
      +  367  2
                   for (Identifier i : this.getIdentifiers()) {
      +  368  0
                       if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
      +  369  0
                           found = true;
      +  370  0
                           i.setConfidence(Confidence.HIGHEST);
      +  371  0
                           final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22";
      +  372  0
                           i.setUrl(url);
       373   -
           /**
      -  374   -
            * Set the value of suppressedIdentifiers.
      -  375   -
            *
      +
                           //i.setUrl(mavenArtifact.getArtifactUrl());
      +  374  0
                           LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue());
      +  375  0
                           break;
       376   -
            * @param suppressedIdentifiers new value of suppressedIdentifiers
      -  377   -
            */
      -  378   -
           public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) {
      -  379  0
               this.suppressedIdentifiers = suppressedIdentifiers;
      -  380  0
           }
      +
                       }
      +  377  0
                   }
      +  378  2
                   if (!found) {
      +  379  2
                       LOGGER.debug("Adding new maven identifier {}", mavenArtifact);
      +  380  2
                       this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
       381   -
       
      +
                   }
       382   -
           /**
      -  383   -
            * Adds an identifier to the list of suppressed identifiers.
      +
               }
      +  383  4
           }
       384   -
            *
      +
       
       385   -
            * @param identifier an identifier that was suppressed.
      +
           /**
       386   -
            */
      +
            * Adds an entry to the list of detected Identifiers for the dependency
       387   -
           public void addSuppressedIdentifier(Identifier identifier) {
      -  388  4
               this.suppressedIdentifiers.add(identifier);
      -  389  4
           }
      +
            * file.
      +  388   +
            *
      +  389   +
            * @param identifier the identifier to add
       390   -
       
      +
            */
       391   -
           /**
      -  392   -
            * A set of vulnerabilities that have been suppressed.
      -  393   -
            */
      +
           public void addIdentifier(Identifier identifier) {
      +  392  6
               this.identifiers.add(identifier);
      +  393  6
           }
       394   -
           private SortedSet<Vulnerability> suppressedVulnerabilities;
      +
       
       395   -
       
      +
           /**
       396   -
           /**
      +
            * A set of identifiers that have been suppressed.
       397   -
            * Get the value of suppressedVulnerabilities.
      +
            */
       398   -
            *
      +
           private Set<Identifier> suppressedIdentifiers;
       399   -
            * @return the value of suppressedVulnerabilities
      +
       
       400   -
            */
      +
           /**
       401   -
           public SortedSet<Vulnerability> getSuppressedVulnerabilities() {
      -  402  3
               return suppressedVulnerabilities;
      +
            * Get the value of suppressedIdentifiers.
      +  402   +
            *
       403   -
           }
      +
            * @return the value of suppressedIdentifiers
       404   -
       
      +
            */
       405   -
           /**
      -  406   -
            * Set the value of suppressedVulnerabilities.
      +
           public Set<Identifier> getSuppressedIdentifiers() {
      +  406  14
               return suppressedIdentifiers;
       407   -
            *
      -  408   -
            * @param suppressedVulnerabilities new value of suppressedVulnerabilities
      -  409   -
            */
      -  410   -
           public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) {
      -  411  0
               this.suppressedVulnerabilities = suppressedVulnerabilities;
      -  412  0
           }
      -  413   -
       
      -  414   -
           /**
      -  415   -
            * Adds a vulnerability to the set of suppressed vulnerabilities.
      -  416   -
            *
      -  417   -
            * @param vulnerability the vulnerability that was suppressed
      -  418   -
            */
      -  419   -
           public void addSuppressedVulnerability(Vulnerability vulnerability) {
      -  420  3
               this.suppressedVulnerabilities.add(vulnerability);
      -  421  3
           }
      -  422   -
       
      -  423   -
           /**
      -  424   -
            * Returns the evidence used to identify this dependency.
      -  425   -
            *
      -  426   -
            * @return an EvidenceCollection.
      -  427   -
            */
      -  428   -
           public EvidenceCollection getEvidence() {
      -  429  11
               return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
      -  430  
           }
      +  408   +
       
      +  409   +
           /**
      +  410   +
            * Set the value of suppressedIdentifiers.
      +  411   +
            *
      +  412   +
            * @param suppressedIdentifiers new value of suppressedIdentifiers
      +  413   +
            */
      +  414   +
           public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) {
      +  415  0
               this.suppressedIdentifiers = suppressedIdentifiers;
      +  416  0
           }
      +  417   +
       
      +  418   +
           /**
      +  419   +
            * Adds an identifier to the list of suppressed identifiers.
      +  420   +
            *
      +  421   +
            * @param identifier an identifier that was suppressed.
      +  422   +
            */
      +  423   +
           public void addSuppressedIdentifier(Identifier identifier) {
      +  424  8
               this.suppressedIdentifiers.add(identifier);
      +  425  8
           }
      +  426   +
       
      +  427   +
           /**
      +  428   +
            * A set of vulnerabilities that have been suppressed.
      +  429   +
            */
      +  430   +
           private SortedSet<Vulnerability> suppressedVulnerabilities;
       431  
       
       432  
           /**
       433   -
            * Returns the evidence used to identify this dependency.
      +
            * Get the value of suppressedVulnerabilities.
       434  
            *
       435   -
            * @return an EvidenceCollection.
      +
            * @return the value of suppressedVulnerabilities
       436  
            */
       437   -
           public Set<Evidence> getEvidenceForDisplay() {
      -  438  0
               return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence);
      +
           public SortedSet<Vulnerability> getSuppressedVulnerabilities() {
      +  438  6
               return suppressedVulnerabilities;
       439  
           }
       440   @@ -812,41 +812,39 @@  441  
           /**
       442   -
            * Returns the evidence used to identify this dependency.
      +
            * Set the value of suppressedVulnerabilities.
       443  
            *
       444   -
            * @return an EvidenceCollection.
      +
            * @param suppressedVulnerabilities new value of suppressedVulnerabilities
       445  
            */
       446   -
           public EvidenceCollection getEvidenceUsed() {
      -  447  1
               return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence);
      -  448   -
           }
      +
           public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) {
      +  447  0
               this.suppressedVulnerabilities = suppressedVulnerabilities;
      +  448  0
           }
       449  
       
       450  
           /**
       451   -
            * Gets the Vendor Evidence.
      +
            * Adds a vulnerability to the set of suppressed vulnerabilities.
       452  
            *
       453   -
            * @return an EvidenceCollection.
      +
            * @param vulnerability the vulnerability that was suppressed
       454  
            */
       455   -
           public EvidenceCollection getVendorEvidence() {
      -  456  135
               return this.vendorEvidence;
      -  457   -
           }
      +
           public void addSuppressedVulnerability(Vulnerability vulnerability) {
      +  456  6
               this.suppressedVulnerabilities.add(vulnerability);
      +  457  6
           }
       458  
       
       459  
           /**
       460   -
            * Gets the Product Evidence.
      +
            * Returns the evidence used to identify this dependency.
       461  
            *
       462   @@ -854,8 +852,8 @@  463  
            */
       464   -
           public EvidenceCollection getProductEvidence() {
      -  465  223
               return this.productEvidence;
      +
           public EvidenceCollection getEvidence() {
      +  465  22
               return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
       466  
           }
       467   @@ -863,7 +861,7 @@  468  
           /**
       469   -
            * Gets the Version Evidence.
      +
            * Returns the evidence used to identify this dependency.
       470  
            *
       471   @@ -871,8 +869,8 @@  472  
            */
       473   -
           public EvidenceCollection getVersionEvidence() {
      -  474  103
               return this.versionEvidence;
      +
           public Set<Evidence> getEvidenceForDisplay() {
      +  474  0
               return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence);
       475  
           }
       476   @@ -880,507 +878,588 @@  477  
           /**
       478   -
            * The description of the JAR file.
      +
            * Returns the evidence used to identify this dependency.
       479   -
            */
      +
            *
       480   -
           private String description;
      +
            * @return an EvidenceCollection.
       481   -
       
      +
            */
       482   -
           /**
      -  483   -
            * Get the value of description.
      +
           public EvidenceCollection getEvidenceUsed() {
      +  483  2
               return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence);
       484   -
            *
      +
           }
       485   -
            * @return the value of description
      +
       
       486   -
            */
      +
           /**
       487   -
           public String getDescription() {
      -  488  9
               return description;
      +
            * Gets the Vendor Evidence.
      +  488   +
            *
       489   -
           }
      +
            * @return an EvidenceCollection.
       490   -
       
      +
            */
       491   -
           /**
      -  492   -
            * Set the value of description.
      +
           public EvidenceCollection getVendorEvidence() {
      +  492  352
               return this.vendorEvidence;
       493   -
            *
      +
           }
       494   -
            * @param description new value of description
      +
       
       495   -
            */
      +
           /**
       496   -
           public void setDescription(String description) {
      -  497  18
               this.description = description;
      -  498  18
           }
      +
            * Gets the Product Evidence.
      +  497   +
            *
      +  498   +
            * @return an EvidenceCollection.
       499   -
       
      +
            */
       500   -
           /**
      -  501   -
            * The license that this dependency uses.
      +
           public EvidenceCollection getProductEvidence() {
      +  501  430
               return this.productEvidence;
       502   -
            */
      +
           }
       503   -
           private String license;
      +
       
       504   -
       
      +
           /**
       505   -
           /**
      +
            * Gets the Version Evidence.
       506   -
            * Get the value of license.
      +
            *
       507   -
            *
      +
            * @return an EvidenceCollection.
       508   -
            * @return the value of license
      +
            */
       509   -
            */
      -  510   -
           public String getLicense() {
      -  511  2
               return license;
      +
           public EvidenceCollection getVersionEvidence() {
      +  510  226
               return this.versionEvidence;
      +  511   +
           }
       512   -
           }
      +
       
       513   -
       
      +
           /**
       514   -
           /**
      +
            * The description of the JAR file.
       515   -
            * Set the value of license.
      +
            */
       516   -
            *
      +
           private String description;
       517   -
            * @param license new value of license
      +
       
       518   -
            */
      +
           /**
       519   -
           public void setLicense(String license) {
      -  520  2
               this.license = license;
      -  521  2
           }
      +
            * Get the value of description.
      +  520   +
            *
      +  521   +
            * @return the value of description
       522   -
       
      +
            */
       523   -
           /**
      -  524   -
            * A list of vulnerabilities for this dependency.
      +
           public String getDescription() {
      +  524  20
               return description;
       525   -
            */
      -  526   -
           private SortedSet<Vulnerability> vulnerabilities;
      -  527   -
       
      -  528   -
           /**
      -  529   -
            * Get the list of vulnerabilities.
      -  530   -
            *
      -  531   -
            * @return the list of vulnerabilities
      -  532   -
            */
      -  533   -
           public SortedSet<Vulnerability> getVulnerabilities() {
      -  534  14
               return vulnerabilities;
      -  535  
           }
      +  526   +
       
      +  527   +
           /**
      +  528   +
            * Set the value of description.
      +  529   +
            *
      +  530   +
            * @param description new value of description
      +  531   +
            */
      +  532   +
           public void setDescription(String description) {
      +  533  40
               this.description = description;
      +  534  40
           }
      +  535   +
       
       536   -
       
      +
           /**
       537   -
           /**
      +
            * The license that this dependency uses.
       538   -
            * Set the value of vulnerabilities.
      +
            */
       539   -
            *
      +
           private String license;
       540   -
            * @param vulnerabilities new value of vulnerabilities
      +
       
       541   -
            */
      +
           /**
       542   -
           public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) {
      -  543  0
               this.vulnerabilities = vulnerabilities;
      -  544  0
           }
      +
            * Get the value of license.
      +  543   +
            *
      +  544   +
            * @return the value of license
       545   -
       
      +
            */
       546   -
           /**
      -  547   -
            * Determines the sha1 and md5 sum for the given file.
      +
           public String getLicense() {
      +  547  4
               return license;
       548   -
            *
      +
           }
       549   -
            * @param file the file to create checksums for
      +
       
       550   -
            */
      +
           /**
       551   -
           private void determineHashes(File file) {
      -  552  67
               String md5 = null;
      -  553  67
               String sha1 = null;
      -  554   -
               try {
      -  555  67
                   md5 = Checksum.getMD5Checksum(file);
      -  556  66
                   sha1 = Checksum.getSHA1Checksum(file);
      -  557  1
               } catch (IOException ex) {
      -  558  1
                   LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName());
      -  559  1
                   LOGGER.debug("", ex);
      -  560  0
               } catch (NoSuchAlgorithmException ex) {
      -  561  0
                   LOGGER.warn("Unable to use MD5 of SHA1 checksums.");
      -  562  0
                   LOGGER.debug("", ex);
      -  563  67
               }
      -  564  67
               this.setMd5sum(md5);
      -  565  67
               this.setSha1sum(sha1);
      -  566  67
           }
      -  567   -
       
      -  568   -
           /**
      -  569   -
            * Adds a vulnerability to the dependency.
      -  570   +
            * Set the value of license.
      +  552  
            *
      -  571   -
            * @param vulnerability a vulnerability outlining a vulnerability.
      -  572   +  553   +
            * @param license new value of license
      +  554  
            */
      -  573   -
           public void addVulnerability(Vulnerability vulnerability) {
      -  574  3
               this.vulnerabilities.add(vulnerability);
      -  575  3
           }
      -  576   +  555   +
           public void setLicense(String license) {
      +  556  4
               this.license = license;
      +  557  4
           }
      +  558  
       
      -  577   +  559  
           /**
      -  578   -
            * A collection of related dependencies.
      -  579   +  560   +
            * A list of vulnerabilities for this dependency.
      +  561  
            */
      -  580  88
           private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
      +  562   +
           private SortedSet<Vulnerability> vulnerabilities;
      +  563   +
       
      +  564   +
           /**
      +  565   +
            * Get the list of vulnerabilities.
      +  566   +
            *
      +  567   +
            * @return the list of vulnerabilities
      +  568   +
            */
      +  569   +
           public SortedSet<Vulnerability> getVulnerabilities() {
      +  570  28
               return vulnerabilities;
      +  571   +
           }
      +  572   +
       
      +  573   +
           /**
      +  574   +
            * Set the value of vulnerabilities.
      +  575   +
            *
      +  576   +
            * @param vulnerabilities new value of vulnerabilities
      +  577   +
            */
      +  578   +
           public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) {
      +  579  0
               this.vulnerabilities = vulnerabilities;
      +  580  0
           }
       581  
       
       582  
           /**
       583   -
            * Get the value of {@link #relatedDependencies}. This field is used to collect other dependencies which really represent the
      +
            * Determines the sha1 and md5 sum for the given file.
       584   -
            * same dependency, and may be presented as one item in reports.
      +
            *
       585   -
            *
      +
            * @param file the file to create checksums for
       586   -
            * @return the value of relatedDependencies
      +
            */
       587   -
            */
      -  588   -
           public Set<Dependency> getRelatedDependencies() {
      -  589  0
               return relatedDependencies;
      +
           private void determineHashes(File file) {
      +  588  142
               String md5 = null;
      +  589  142
               String sha1 = null;
       590   -
           }
      -  591   +
               try {
      +  591  142
                   md5 = Checksum.getMD5Checksum(file);
      +  592  140
                   sha1 = Checksum.getSHA1Checksum(file);
      +  593  2
               } catch (IOException ex) {
      +  594  2
                   LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName());
      +  595  2
                   LOGGER.debug("", ex);
      +  596  0
               } catch (NoSuchAlgorithmException ex) {
      +  597  0
                   LOGGER.warn("Unable to use MD5 of SHA1 checksums.");
      +  598  0
                   LOGGER.debug("", ex);
      +  599  142
               }
      +  600  142
               this.setMd5sum(md5);
      +  601  142
               this.setSha1sum(sha1);
      +  602  142
           }
      +  603  
       
      -  592   -
           /**
      -  593   -
            * A list of projects that reference this dependency.
      -  594   -
            */
      -  595  88
           private Set<String> projectReferences = new HashSet<String>();
      -  596   -
       
      -  597   -
           /**
      -  598   -
            * Get the value of projectReferences.
      -  599   -
            *
      -  600   -
            * @return the value of projectReferences
      -  601   -
            */
      -  602   -
           public Set<String> getProjectReferences() {
      -  603  0
               return projectReferences;
       604   -
           }
      +
           /**
       605   -
       
      +
            * Adds a vulnerability to the dependency.
       606   -
           /**
      +
            *
       607   -
            * Set the value of projectReferences.
      +
            * @param vulnerability a vulnerability outlining a vulnerability.
       608   -
            *
      +
            */
       609   -
            * @param projectReferences new value of projectReferences
      -  610   -
            */
      -  611   -
           public void setProjectReferences(Set<String> projectReferences) {
      -  612  0
               this.projectReferences = projectReferences;
      -  613  0
           }
      +
           public void addVulnerability(Vulnerability vulnerability) {
      +  610  6
               this.vulnerabilities.add(vulnerability);
      +  611  6
           }
      +  612   +
       
      +  613   +
           /**
       614   -
       
      +
            * A collection of related dependencies.
       615   -
           /**
      -  616   -
            * Adds a project reference.
      +
            */
      +  616  184
           private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
       617   -
            *
      +
       
       618   -
            * @param projectReference a project reference
      +
           /**
       619   -
            */
      +
            * Get the value of {@link #relatedDependencies}. This field is used to
       620   -
           public void addProjectReference(String projectReference) {
      -  621  0
               this.projectReferences.add(projectReference);
      -  622  0
           }
      +
            * collect other dependencies which really represent the same dependency,
      +  621   +
            * and may be presented as one item in reports.
      +  622   +
            *
       623   -
       
      +
            * @return the value of relatedDependencies
       624   -
           /**
      +
            */
       625   -
            * Add a collection of project reference.
      -  626   -
            *
      +
           public Set<Dependency> getRelatedDependencies() {
      +  626  0
               return relatedDependencies;
       627   -
            * @param projectReferences a set of project references
      +
           }
       628   -
            */
      +
       
       629   -
           public void addAllProjectReferences(Set<String> projectReferences) {
      -  630  0
               this.projectReferences.addAll(projectReferences);
      -  631  0
           }
      -  632   -
       
      +
           /**
      +  630   +
            * A list of projects that reference this dependency.
      +  631   +
            */
      +  632  184
           private Set<String> projectReferences = new HashSet<String>();
       633   -
           /**
      +
       
       634   -
            * Set the value of relatedDependencies.
      +
           /**
       635   -
            *
      +
            * Get the value of projectReferences.
       636   -
            * @param relatedDependencies new value of relatedDependencies
      +
            *
       637   -
            */
      +
            * @return the value of projectReferences
       638   -
           public void setRelatedDependencies(Set<Dependency> relatedDependencies) {
      -  639  0
               this.relatedDependencies = relatedDependencies;
      -  640  0
           }
      +
            */
      +  639   +
           public Set<String> getProjectReferences() {
      +  640  0
               return projectReferences;
       641   -
       
      +
           }
       642   -
           /**
      +
       
       643   -
            * Adds a related dependency. The internal collection is normally a {@link java.util.TreeSet}, which relies on
      +
           /**
       644   -
            * {@link #compareTo(Dependency)}. A consequence of this is that if you attempt to add a dependency with the same file path
      +
            * Set the value of projectReferences.
       645   -
            * (modulo character case) as one that is already in the collection, it won't get added.
      +
            *
       646   -
            *
      +
            * @param projectReferences new value of projectReferences
       647   -
            * @param dependency a reference to the related dependency
      +
            */
       648   -
            */
      -  649   -
           public void addRelatedDependency(Dependency dependency) {
      -  650  0
               if (this == dependency) {
      -  651  0
                   LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here "
      +
           public void setProjectReferences(Set<String> projectReferences) {
      +  649  0
               this.projectReferences = projectReferences;
      +  650  0
           }
      +  651   +
       
       652   -
                           + "https://github.com/jeremylong/DependencyCheck/issues/172");
      -  653  0
                   LOGGER.debug("this: {}", this);
      -  654  0
                   LOGGER.debug("dependency: {}", dependency);
      -  655  0
               } else if (!relatedDependencies.add(dependency)) {
      -  656  0
                   LOGGER.debug("Failed to add dependency, likely due to referencing the same file as another dependency in the set.");
      -  657  0
                   LOGGER.debug("this: {}", this);
      -  658  0
                   LOGGER.debug("dependency: {}", dependency);
      -  659   -
               }
      -  660  0
           }
      +
           /**
      +  653   +
            * Adds a project reference.
      +  654   +
            *
      +  655   +
            * @param projectReference a project reference
      +  656   +
            */
      +  657   +
           public void addProjectReference(String projectReference) {
      +  658  0
               this.projectReferences.add(projectReference);
      +  659  0
           }
      +  660   +
       
       661   -
       
      +
           /**
       662   -
           /**
      +
            * Add a collection of project reference.
       663   -
            * A list of available versions.
      +
            *
       664   +
            * @param projectReferences a set of project references
      +  665  
            */
      -  665  88
           private List<String> availableVersions = new ArrayList<String>();
       666   -
       
      -  667   -
           /**
      -  668   -
            * Get the value of availableVersions.
      +
           public void addAllProjectReferences(Set<String> projectReferences) {
      +  667  0
               this.projectReferences.addAll(projectReferences);
      +  668  0
           }
       669   -
            *
      +
       
       670   -
            * @return the value of availableVersions
      +
           /**
       671   -
            */
      +
            * Set the value of relatedDependencies.
       672   -
           public List<String> getAvailableVersions() {
      -  673  0
               return availableVersions;
      +
            *
      +  673   +
            * @param relatedDependencies new value of relatedDependencies
       674   -
           }
      +
            */
       675   -
       
      -  676   -
           /**
      -  677   -
            * Set the value of availableVersions.
      +
           public void setRelatedDependencies(Set<Dependency> relatedDependencies) {
      +  676  0
               this.relatedDependencies = relatedDependencies;
      +  677  0
           }
       678   -
            *
      +
       
       679   -
            * @param availableVersions new value of availableVersions
      +
           /**
       680   -
            */
      +
            * Adds a related dependency. The internal collection is normally a
       681   -
           public void setAvailableVersions(List<String> availableVersions) {
      -  682  0
               this.availableVersions = availableVersions;
      -  683  0
           }
      +
            * {@link java.util.TreeSet}, which relies on
      +  682   +
            * {@link #compareTo(Dependency)}. A consequence of this is that if you
      +  683   +
            * attempt to add a dependency with the same file path (modulo character
       684   -
       
      +
            * case) as one that is already in the collection, it won't get added.
       685   -
           /**
      +
            *
       686   -
            * Adds a version to the available version list.
      +
            * @param dependency a reference to the related dependency
       687   -
            *
      +
            */
       688   -
            * @param version the version to add to the list
      -  689   -
            */
      -  690   -
           public void addAvailableVersion(String version) {
      -  691  0
               this.availableVersions.add(version);
      -  692  0
           }
      -  693   -
       
      -  694   -
           /**
      -  695   -
            * Implementation of the Comparable&lt;Dependency&gt; interface. The comparison is solely based on the file path.
      -  696   -
            *
      -  697   -
            * @param o a dependency to compare
      +
           public void addRelatedDependency(Dependency dependency) {
      +  689  0
               if (this == dependency) {
      +  690  0
                   LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here "
      +  691   +
                           + "https://github.com/jeremylong/DependencyCheck/issues/172");
      +  692  0
                   LOGGER.debug("this: {}", this);
      +  693  0
                   LOGGER.debug("dependency: {}", dependency);
      +  694  0
               } else if (!relatedDependencies.add(dependency)) {
      +  695  0
                   LOGGER.debug("Failed to add dependency, likely due to referencing the same file as another dependency in the set.");
      +  696  0
                   LOGGER.debug("this: {}", this);
      +  697  0
                   LOGGER.debug("dependency: {}", dependency);
       698   -
            * @return an integer representing the natural ordering
      -  699   -
            */
      +
               }
      +  699  0
           }
       700   -
           @Override
      -  701   -
           public int compareTo(Dependency o) {
      -  702  2
               return this.getFilePath().compareToIgnoreCase(o.getFilePath());
      -  703   -
           }
      -  704  
       
      -  705   +  701  
           /**
      +  702   +
            * A list of available versions.
      +  703   +
            */
      +  704  184
           private List<String> availableVersions = new ArrayList<String>();
      +  705   +
       
       706   -
            * Implementation of the equals method.
      +
           /**
       707   -
            *
      +
            * Get the value of availableVersions.
       708   -
            * @param obj the object to compare
      +
            *
       709   -
            * @return true if the objects are equal, otherwise false
      +
            * @return the value of availableVersions
       710  
            */
       711   -
           @Override
      -  712   -
           public boolean equals(Object obj) {
      -  713  0
               if (obj == null || getClass() != obj.getClass()) {
      -  714  0
                   return false;
      +
           public List<String> getAvailableVersions() {
      +  712  0
               return availableVersions;
      +  713   +
           }
      +  714   +
       
       715   -
               }
      -  716  0
               final Dependency other = (Dependency) obj;
      -  717  0
               return new EqualsBuilder()
      -  718  0
                       .appendSuper(super.equals(obj))
      -  719  0
                       .append(this.actualFilePath, other.actualFilePath)
      -  720  0
                       .append(this.filePath, other.filePath)
      -  721  0
                       .append(this.fileName, other.fileName)
      -  722  0
                       .append(this.md5sum, other.md5sum)
      -  723  0
                       .append(this.sha1sum, other.sha1sum)
      -  724  0
                       .append(this.identifiers, other.identifiers)
      -  725  0
                       .append(this.vendorEvidence, other.vendorEvidence)
      -  726  0
                       .append(this.productEvidence, other.productEvidence)
      -  727  0
                       .append(this.versionEvidence, other.versionEvidence)
      -  728  0
                       .append(this.description, other.description)
      -  729  0
                       .append(this.license, other.license)
      -  730  0
                       .append(this.vulnerabilities, other.vulnerabilities)
      -  731   -
                       //.append(this.relatedDependencies, other.relatedDependencies)
      -  732  0
                       .append(this.projectReferences, other.projectReferences)
      -  733  0
                       .append(this.availableVersions, other.availableVersions)
      -  734  0
                       .isEquals();
      +
           /**
      +  716   +
            * Set the value of availableVersions.
      +  717   +
            *
      +  718   +
            * @param availableVersions new value of availableVersions
      +  719   +
            */
      +  720   +
           public void setAvailableVersions(List<String> availableVersions) {
      +  721  0
               this.availableVersions = availableVersions;
      +  722  0
           }
      +  723   +
       
      +  724   +
           /**
      +  725   +
            * Adds a version to the available version list.
      +  726   +
            *
      +  727   +
            * @param version the version to add to the list
      +  728   +
            */
      +  729   +
           public void addAvailableVersion(String version) {
      +  730  0
               this.availableVersions.add(version);
      +  731  0
           }
      +  732   +
       
      +  733   +
           /**
      +  734   +
            * Implementation of the Comparable&lt;Dependency&gt; interface. The
       735   -
           }
      +
            * comparison is solely based on the file path.
       736   -
       
      +
            *
       737   -
           /**
      +
            * @param o a dependency to compare
       738   -
            * Generates the HashCode.
      +
            * @return an integer representing the natural ordering
       739   -
            *
      +
            */
       740   -
            * @return the HashCode
      +
           @Override
       741   -
            */
      -  742   -
           @Override
      +
           public int compareTo(Dependency o) {
      +  742  4
               return this.getFilePath().compareToIgnoreCase(o.getFilePath());
       743   -
           public int hashCode() {
      -  744  49
               return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
      -  745  49
                       .append(actualFilePath)
      -  746  49
                       .append(filePath)
      -  747  49
                       .append(fileName)
      -  748  49
                       .append(md5sum)
      -  749  49
                       .append(sha1sum)
      -  750  49
                       .append(identifiers)
      -  751  49
                       .append(vendorEvidence)
      -  752  49
                       .append(productEvidence)
      -  753  49
                       .append(versionEvidence)
      -  754  49
                       .append(description)
      -  755  49
                       .append(license)
      -  756  49
                       .append(vulnerabilities)
      -  757   -
                       //.append(relatedDependencies)
      -  758  49
                       .append(projectReferences)
      -  759  49
                       .append(availableVersions)
      -  760  49
                       .toHashCode();
      -  761  
           }
      -  762   +  744  
       
      -  763   +  745  
           /**
      -  764   -
            * Standard toString() implementation showing the filename, actualFilePath, and filePath.
      -  765   +  746   +
            * Implementation of the equals method.
      +  747  
            *
      -  766   -
            * @return the string representation of the file
      -  767   +  748   +
            * @param obj the object to compare
      +  749   +
            * @return true if the objects are equal, otherwise false
      +  750  
            */
      -  768   +  751  
           @Override
      -  769   -
           public String toString() {
      -  770  30
               return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}";
      -  771   -
           }
      +  752   +
           public boolean equals(Object obj) {
      +  753  0
               if (obj == null || getClass() != obj.getClass()) {
      +  754  0
                   return false;
      +  755   +
               }
      +  756  0
               final Dependency other = (Dependency) obj;
      +  757  0
               return new EqualsBuilder()
      +  758  0
                       .appendSuper(super.equals(obj))
      +  759  0
                       .append(this.actualFilePath, other.actualFilePath)
      +  760  0
                       .append(this.filePath, other.filePath)
      +  761  0
                       .append(this.fileName, other.fileName)
      +  762  0
                       .append(this.packagePath, other.packagePath)
      +  763  0
                       .append(this.md5sum, other.md5sum)
      +  764  0
                       .append(this.sha1sum, other.sha1sum)
      +  765  0
                       .append(this.identifiers, other.identifiers)
      +  766  0
                       .append(this.vendorEvidence, other.vendorEvidence)
      +  767  0
                       .append(this.productEvidence, other.productEvidence)
      +  768  0
                       .append(this.versionEvidence, other.versionEvidence)
      +  769  0
                       .append(this.description, other.description)
      +  770  0
                       .append(this.license, other.license)
      +  771  0
                       .append(this.vulnerabilities, other.vulnerabilities)
       772   +
                       //.append(this.relatedDependencies, other.relatedDependencies)
      +  773  0
                       .append(this.projectReferences, other.projectReferences)
      +  774  0
                       .append(this.availableVersions, other.availableVersions)
      +  775  0
                       .isEquals();
      +  776   +
           }
      +  777   +
       
      +  778   +
           /**
      +  779   +
            * Generates the HashCode.
      +  780   +
            *
      +  781   +
            * @return the HashCode
      +  782   +
            */
      +  783   +
           @Override
      +  784   +
           public int hashCode() {
      +  785  408
               return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
      +  786  204
                       .append(actualFilePath)
      +  787  204
                       .append(filePath)
      +  788  204
                       .append(fileName)
      +  789  204
                       .append(md5sum)
      +  790  204
                       .append(sha1sum)
      +  791  204
                       .append(identifiers)
      +  792  204
                       .append(vendorEvidence)
      +  793  204
                       .append(productEvidence)
      +  794  204
                       .append(versionEvidence)
      +  795  204
                       .append(description)
      +  796  204
                       .append(license)
      +  797  204
                       .append(vulnerabilities)
      +  798   +
                       //.append(relatedDependencies)
      +  799  204
                       .append(projectReferences)
      +  800  204
                       .append(availableVersions)
      +  801  204
                       .toHashCode();
      +  802   +
           }
      +  803   +
       
      +  804   +
           /**
      +  805   +
            * Standard toString() implementation showing the filename, actualFilePath,
      +  806   +
            * and filePath.
      +  807   +
            *
      +  808   +
            * @return the string representation of the file
      +  809   +
            */
      +  810   +
           @Override
      +  811   +
           public String toString() {
      +  812  60
               return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath
      +  813   +
                       + "', filePath='" + filePath + "', packagePath='" + packagePath + "'}";
      +  814   +
           }
      +  815  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html index b498508e5..8e2ea17e0 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  601
       public class Evidence implements Serializable, Comparable<Evidence> {
      +  31  1394
       public class Evidence implements Serializable, Comparable<Evidence> {
       32  
       
       33   @@ -134,12 +134,12 @@
            * @param confidence the confidence of the evidence.
       60  
            */
      -  61  340
           public Evidence(String source, String name, String value, Confidence confidence) {
      -  62  340
               this.source = source;
      -  63  340
               this.name = name;
      -  64  340
               this.value = value;
      -  65  340
               this.confidence = confidence;
      -  66  340
           }
      +  61  798
           public Evidence(String source, String name, String value, Confidence confidence) {
      +  62  798
               this.source = source;
      +  63  798
               this.name = name;
      +  64  798
               this.value = value;
      +  65  798
               this.confidence = confidence;
      +  66  798
           }
       67  
       
       68   @@ -164,7 +164,7 @@
            */
       78  
           public String getName() {
      -  79  18
               return name;
      +  79  74
               return name;
       80  
           }
       81   @@ -207,7 +207,7 @@
            */
       101  
           public String getSource() {
      -  102  16
               return source;
      +  102  60
               return source;
       103  
           }
       104   @@ -250,8 +250,8 @@
            */
       124  
           public String getValue() {
      -  125  469
               used = true;
      -  126  469
               return value;
      +  125  936
               used = true;
      +  126  936
               return value;
       127  
           }
       128   @@ -270,8 +270,8 @@
            */
       135  
           public String getValue(Boolean setUsed) {
      -  136  36
               used = used || setUsed;
      -  137  36
               return value;
      +  136  100
               used = used || setUsed;
      +  137  100
               return value;
       138  
           }
       139   @@ -314,7 +314,7 @@
            */
       159  
           public boolean isUsed() {
      -  160  1188
               return used;
      +  160  1248
               return used;
       161  
           }
       162   @@ -357,7 +357,7 @@
            */
       182  
           public Confidence getConfidence() {
      -  183  182
               return confidence;
      +  183  512
               return confidence;
       184  
           }
       185   @@ -392,12 +392,12 @@
           @Override
       201  
           public int hashCode() {
      -  202  8
               return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
      -  203  8
                   .append(StringUtils.lowerCase(name))
      -  204  8
                   .append(StringUtils.lowerCase(source))
      -  205  8
                   .append(StringUtils.lowerCase(value))
      -  206  8
                   .append(confidence)
      -  207  8
                   .toHashCode();
      +  202  32
               return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
      +  203  16
                   .append(StringUtils.lowerCase(name))
      +  204  16
                   .append(StringUtils.lowerCase(source))
      +  205  16
                   .append(StringUtils.lowerCase(value))
      +  206  16
                   .append(confidence)
      +  207  16
                   .toHashCode();
       208  
           }
       209   @@ -418,21 +418,21 @@
           @Override
       217  
           public boolean equals(Object that) {
      -  218  10
               if (this == that) {
      +  218  20
               if (this == that) {
       219  0
                   return true;
       220  
               }
      -  221  10
               if (!(that instanceof Evidence)) {
      +  221  20
               if (!(that instanceof Evidence)) {
       222  0
                   return false;
       223  
               }
      -  224  10
               final Evidence e = (Evidence) that;
      +  224  20
               final Evidence e = (Evidence) that;
       225  
       
      -  226  10
               return StringUtils.equalsIgnoreCase(name, e.name)
      -  227  2
                       && StringUtils.equalsIgnoreCase(source, e.source)
      -  228  2
                       && StringUtils.equalsIgnoreCase(value, e.value)
      -  229  2
                       && ObjectUtils.equals(confidence, e.confidence);
      +  226  40
               return StringUtils.equalsIgnoreCase(name, e.name)
      +  227  4
                       && StringUtils.equalsIgnoreCase(source, e.source)
      +  228  4
                       && StringUtils.equalsIgnoreCase(value, e.value)
      +  229  4
                       && ObjectUtils.equals(confidence, e.confidence);
       230  
           }
       231   @@ -453,33 +453,33 @@
           @Override
       239  
           public int compareTo(Evidence o) {
      -  240  611
               if (o == null) {
      +  240  1414
               if (o == null) {
       241  0
                   return 1;
       242  
               }
      -  243  611
               if (StringUtils.equalsIgnoreCase(source, o.source)) {
      -  244  394
                   if (StringUtils.equalsIgnoreCase(name, o.name)) {
      -  245  237
                       if (StringUtils.equalsIgnoreCase(value, o.value)) {
      -  246  203
                           if (ObjectUtils.equals(confidence, o.confidence)) {
      -  247  201
                               return 0; //they are equal
      +  243  1414
               if (StringUtils.equalsIgnoreCase(source, o.source)) {
      +  244  912
                   if (StringUtils.equalsIgnoreCase(name, o.name)) {
      +  245  500
                       if (StringUtils.equalsIgnoreCase(value, o.value)) {
      +  246  444
                           if (ObjectUtils.equals(confidence, o.confidence)) {
      +  247  440
                               return 0; //they are equal
       248  
                           } else {
      -  249  2
                               return ObjectUtils.compare(confidence, o.confidence);
      +  249  4
                               return ObjectUtils.compare(confidence, o.confidence);
       250  
                           }
       251  
                       } else {
      -  252  34
                           return compareToIgnoreCaseWithNullCheck(value, o.value);
      +  252  56
                           return compareToIgnoreCaseWithNullCheck(value, o.value);
       253  
                       }
       254  
                   } else {
      -  255  157
                       return compareToIgnoreCaseWithNullCheck(name, o.name);
      +  255  412
                       return compareToIgnoreCaseWithNullCheck(name, o.name);
       256  
                   }
       257  
               } else {
      -  258  217
                   return compareToIgnoreCaseWithNullCheck(source, o.source);
      +  258  502
                   return compareToIgnoreCaseWithNullCheck(source, o.source);
       259  
               }
       260   @@ -504,15 +504,15 @@
            */
       270  
           private int compareToIgnoreCaseWithNullCheck(String me, String other) {
      -  271  408
               if (me == null && other == null) {
      +  271  970
               if (me == null && other == null) {
       272  0
                   return 0;
      -  273  408
               } else if (me == null) {
      +  273  970
               } else if (me == null) {
       274  0
                   return -1; //the other string is greater then me
      -  275  408
               } else if (other == null) {
      +  275  970
               } else if (other == null) {
       276  0
                   return 1; //me is greater then the other string
       277  
               }
      -  278  408
               return me.compareToIgnoreCase(other);
      +  278  970
               return me.compareToIgnoreCase(other);
       279  
           }
       280   @@ -538,6 +538,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html index 2fa072481..48ed478bd 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html @@ -118,19 +118,19 @@
            * The logger.
       48  
            */
      -  49  1
           private static final Logger LOGGER = LoggerFactory.getLogger(EvidenceCollection.class);
      +  49  2
           private static final Logger LOGGER = LoggerFactory.getLogger(EvidenceCollection.class);
       50  
           /**
       51  
            * Used to iterate over highest confidence evidence contained in the collection.
       52  
            */
      -  53  49
           private static final Filter<Evidence> HIGHEST_CONFIDENCE = new Filter<Evidence>() {
      +  53  44
           private static final Filter<Evidence> HIGHEST_CONFIDENCE = new Filter<Evidence>() {
       54  
               @Override
       55  
               public boolean passes(Evidence evidence) {
      -  56  48
                   return evidence.getConfidence() == Confidence.HIGHEST;
      +  56  42
                   return evidence.getConfidence() == Confidence.HIGHEST;
       57  
               }
       58   @@ -141,12 +141,12 @@
            * Used to iterate over high confidence evidence contained in the collection.
       61  
            */
      -  62  33
           private static final Filter<Evidence> HIGH_CONFIDENCE = new Filter<Evidence>() {
      +  62  124
           private static final Filter<Evidence> HIGH_CONFIDENCE = new Filter<Evidence>() {
       63  
               @Override
       64  
               public boolean passes(Evidence evidence) {
      -  65  32
                   return evidence.getConfidence() == Confidence.HIGH;
      +  65  122
                   return evidence.getConfidence() == Confidence.HIGH;
       66  
               }
       67   @@ -157,12 +157,12 @@
            * Used to iterate over medium confidence evidence contained in the collection.
       70  
            */
      -  71  31
           private static final Filter<Evidence> MEDIUM_CONFIDENCE = new Filter<Evidence>() {
      +  71  74
           private static final Filter<Evidence> MEDIUM_CONFIDENCE = new Filter<Evidence>() {
       72  
               @Override
       73  
               public boolean passes(Evidence evidence) {
      -  74  30
                   return evidence.getConfidence() == Confidence.MEDIUM;
      +  74  72
                   return evidence.getConfidence() == Confidence.MEDIUM;
       75  
               }
       76   @@ -173,12 +173,12 @@
            * Used to iterate over low confidence evidence contained in the collection.
       79  
            */
      -  80  31
           private static final Filter<Evidence> LOW_CONFIDENCE = new Filter<Evidence>() {
      +  80  80
           private static final Filter<Evidence> LOW_CONFIDENCE = new Filter<Evidence>() {
       81  
               @Override
       82  
               public boolean passes(Evidence evidence) {
      -  83  30
                   return evidence.getConfidence() == Confidence.LOW;
      +  83  78
                   return evidence.getConfidence() == Confidence.LOW;
       84  
               }
       85   @@ -189,12 +189,12 @@
            * Used to iterate over evidence that has was used (aka read) from the collection.
       88  
            */
      -  89  1187
           private static final Filter<Evidence> EVIDENCE_USED = new Filter<Evidence>() {
      +  89  1246
           private static final Filter<Evidence> EVIDENCE_USED = new Filter<Evidence>() {
       90  
               @Override
       91  
               public boolean passes(Evidence evidence) {
      -  92  1186
                   return evidence.isUsed();
      +  92  1244
                   return evidence.isUsed();
       93  
               }
       94   @@ -215,15 +215,15 @@
            */
       102  
           public final Iterable<Evidence> iterator(Confidence confidence) {
      -  103  23
               if (confidence == Confidence.HIGHEST) {
      -  104  7
                   return EvidenceCollection.HIGHEST_CONFIDENCE.filter(this.list);
      -  105  16
               } else if (confidence == Confidence.HIGH) {
      -  106  6
                   return EvidenceCollection.HIGH_CONFIDENCE.filter(this.list);
      -  107  10
               } else if (confidence == Confidence.MEDIUM) {
      -  108  5
                   return EvidenceCollection.MEDIUM_CONFIDENCE.filter(this.list);
      +  103  60
               if (confidence == Confidence.HIGHEST) {
      +  104  10
                   return EvidenceCollection.HIGHEST_CONFIDENCE.filter(this.list);
      +  105  50
               } else if (confidence == Confidence.HIGH) {
      +  106  24
                   return EvidenceCollection.HIGH_CONFIDENCE.filter(this.list);
      +  107  26
               } else if (confidence == Confidence.MEDIUM) {
      +  108  12
                   return EvidenceCollection.MEDIUM_CONFIDENCE.filter(this.list);
       109  
               } else {
      -  110  5
                   return EvidenceCollection.LOW_CONFIDENCE.filter(this.list);
      +  110  14
                   return EvidenceCollection.LOW_CONFIDENCE.filter(this.list);
       111  
               }
       112   @@ -252,10 +252,10 @@
            * Creates a new EvidenceCollection.
       124  
            */
      -  125  276
           public EvidenceCollection() {
      -  126  276
               list = new TreeSet<Evidence>();
      -  127  276
               weightedStrings = new HashSet<String>();
      -  128  276
           }
      +  125  576
           public EvidenceCollection() {
      +  126  576
               list = new TreeSet<Evidence>();
      +  127  576
               weightedStrings = new HashSet<String>();
      +  128  576
           }
       129  
       
       130   @@ -270,8 +270,8 @@
            */
       135  
           public void addEvidence(Evidence e) {
      -  136  292
               list.add(e);
      -  137  292
           }
      +  136  666
               list.add(e);
      +  137  666
           }
       138  
       
       139   @@ -292,9 +292,9 @@
            */
       147  
           public void addEvidence(String source, String name, String value, Confidence confidence) {
      -  148  285
               final Evidence e = new Evidence(source, name, value, confidence);
      -  149  285
               addEvidence(e);
      -  150  285
           }
      +  148  652
               final Evidence e = new Evidence(source, name, value, confidence);
      +  149  652
               addEvidence(e);
      +  150  652
           }
       151  
       
       152   @@ -321,8 +321,8 @@
            */
       163  
           public void addWeighting(String str) {
      -  164  15
               weightedStrings.add(str);
      -  165  15
           }
      +  164  30
               weightedStrings.add(str);
      +  165  30
           }
       166  
       
       167   @@ -339,7 +339,7 @@
            */
       173  
           public Set<String> getWeighting() {
      -  174  13
               return weightedStrings;
      +  174  46
               return weightedStrings;
       175  
           }
       176   @@ -356,7 +356,7 @@
            */
       182  
           public Set<Evidence> getEvidence() {
      -  183  9
               return list;
      +  183  38
               return list;
       184  
           }
       185   @@ -375,18 +375,18 @@
            */
       192  
           public Set<Evidence> getEvidence(String source) {
      -  193  1
               if (source == null) {
      +  193  2
               if (source == null) {
       194  0
                   return null;
       195  
               }
      -  196  1
               final Set<Evidence> ret = new HashSet<Evidence>();
      -  197  1
               for (Evidence e : list) {
      -  198  5
                   if (source.equals(e.getSource())) {
      -  199  1
                       ret.add(e);
      +  196  2
               final Set<Evidence> ret = new HashSet<Evidence>();
      +  197  2
               for (Evidence e : list) {
      +  198  10
                   if (source.equals(e.getSource())) {
      +  199  2
                       ret.add(e);
       200  
                   }
      -  201  5
               }
      -  202  1
               return ret;
      +  201  10
               }
      +  202  2
               return ret;
       203  
           }
       204   @@ -407,18 +407,18 @@
            */
       212  
           public Set<Evidence> getEvidence(String source, String name) {
      -  213  8
               if (source == null || name == null) {
      +  213  16
               if (source == null || name == null) {
       214  0
                   return null;
       215  
               }
      -  216  8
               final Set<Evidence> ret = new HashSet<Evidence>();
      -  217  8
               for (Evidence e : list) {
      -  218  11
                   if (source.equals(e.getSource()) && name.equals(e.getName())) {
      -  219  5
                       ret.add(e);
      +  216  16
               final Set<Evidence> ret = new HashSet<Evidence>();
      +  217  16
               for (Evidence e : list) {
      +  218  22
                   if (source.equals(e.getSource()) && name.equals(e.getName())) {
      +  219  10
                       ret.add(e);
       220  
                   }
      -  221  11
               }
      -  222  8
               return ret;
      +  221  22
               }
      +  222  16
               return ret;
       223  
           }
       224   @@ -437,7 +437,7 @@
           @Override
       231  
           public Iterator<Evidence> iterator() {
      -  232  158
               return list.iterator();
      +  232  214
               return list.iterator();
       233  
           }
       234   @@ -456,23 +456,23 @@
            */
       241  
           public boolean containsUsedString(String text) {
      -  242  146
               if (text == null) {
      +  242  184
               if (text == null) {
       243  0
                   return false;
       244  
               }
      -  245  146
               final String textToTest = text.toLowerCase();
      +  245  184
               final String textToTest = text.toLowerCase();
       246  
       
      -  247  146
               for (Evidence e : EvidenceCollection.EVIDENCE_USED.filter(this)) {
      +  247  184
               for (Evidence e : EvidenceCollection.EVIDENCE_USED.filter(this)) {
       248  
                   //TODO consider changing the regex to only compare alpha-numeric (i.e. strip everything else)
      -  249  344
                   final String value = urlCorrection(e.getValue().toLowerCase()).replaceAll("[\\s_-]", "");
      -  250  344
                   if (value.contains(textToTest)) {
      -  251  27
                       return true;
      +  249  612
                   final String value = urlCorrection(e.getValue().toLowerCase()).replaceAll("[\\s_-]", "");
      +  250  612
                   if (value.contains(textToTest)) {
      +  251  48
                       return true;
       252  
                   }
      -  253  317
               }
      -  254  119
               return false;
      +  253  564
               }
      +  254  136
               return false;
       255  
           }
       256   @@ -523,13 +523,13 @@
            */
       283  
           public boolean contains(Confidence confidence) {
      -  284  14
               for (Evidence e : list) {
      -  285  42
                   if (e.getConfidence().equals(confidence)) {
      -  286  11
                       return true;
      +  284  60
               for (Evidence e : list) {
      +  285  170
                   if (e.getConfidence().equals(confidence)) {
      +  286  36
                       return true;
       287  
                   }
      -  288  31
               }
      -  289  3
               return false;
      +  288  134
               }
      +  289  24
               return false;
       290  
           }
       291   @@ -548,17 +548,17 @@
            */
       298  
           public static EvidenceCollection mergeUsed(EvidenceCollection... ec) {
      -  299  1
               final EvidenceCollection ret = new EvidenceCollection();
      -  300  4
               for (EvidenceCollection col : ec) {
      -  301  3
                   for (Evidence e : col.list) {
      -  302  2
                       if (e.isUsed()) {
      -  303  1
                           ret.addEvidence(e);
      +  299  2
               final EvidenceCollection ret = new EvidenceCollection();
      +  300  8
               for (EvidenceCollection col : ec) {
      +  301  6
                   for (Evidence e : col.list) {
      +  302  4
                       if (e.isUsed()) {
      +  303  2
                           ret.addEvidence(e);
       304  
                       }
      -  305  2
                   }
      +  305  4
                   }
       306  
               }
      -  307  1
               return ret;
      +  307  2
               return ret;
       308  
           }
       309   @@ -577,13 +577,13 @@
            */
       316  
           public static EvidenceCollection merge(EvidenceCollection... ec) {
      -  317  11
               final EvidenceCollection ret = new EvidenceCollection();
      -  318  44
               for (EvidenceCollection col : ec) {
      -  319  33
                   ret.list.addAll(col.list);
      -  320  33
                   ret.weightedStrings.addAll(col.weightedStrings);
      +  317  22
               final EvidenceCollection ret = new EvidenceCollection();
      +  318  88
               for (EvidenceCollection col : ec) {
      +  319  66
                   ret.list.addAll(col.list);
      +  320  66
                   ret.weightedStrings.addAll(col.weightedStrings);
       321  
               }
      -  322  11
               return ret;
      +  322  22
               return ret;
       323  
           }
       324   @@ -634,11 +634,11 @@
           @Override
       351  
           public String toString() {
      -  352  39
               final StringBuilder sb = new StringBuilder();
      -  353  39
               for (Evidence e : this.list) {
      -  354  74
                   sb.append(e.getValue()).append(' ');
      -  355  74
               }
      -  356  39
               return sb.toString();
      +  352  86
               final StringBuilder sb = new StringBuilder();
      +  353  86
               for (Evidence e : this.list) {
      +  354  170
                   sb.append(e.getValue()).append(' ');
      +  355  170
               }
      +  356  86
               return sb.toString();
       357  
           }
       358   @@ -655,7 +655,7 @@
            */
       364  
           public int size() {
      -  365  12
               return list.size();
      +  365  38
               return list.size();
       366  
           }
       367   @@ -698,22 +698,22 @@
            */
       386  
           private String urlCorrection(String value) {
      -  387  344
               if (value == null || !UrlStringUtils.containsUrl(value)) {
      -  388  325
                   return value;
      +  387  612
               if (value == null || !UrlStringUtils.containsUrl(value)) {
      +  388  574
                   return value;
       389  
               }
      -  390  19
               final StringBuilder sb = new StringBuilder(value.length());
      -  391  19
               final String[] parts = value.split("\\s");
      -  392  38
               for (String part : parts) {
      -  393  19
                   if (UrlStringUtils.isUrl(part)) {
      +  390  38
               final StringBuilder sb = new StringBuilder(value.length());
      +  391  38
               final String[] parts = value.split("\\s");
      +  392  76
               for (String part : parts) {
      +  393  38
                   if (UrlStringUtils.isUrl(part)) {
       394  
                       try {
      -  395  19
                           final List<String> data = UrlStringUtils.extractImportantUrlData(part);
      -  396  19
                           sb.append(' ').append(StringUtils.join(data, ' '));
      +  395  38
                           final List<String> data = UrlStringUtils.extractImportantUrlData(part);
      +  396  38
                           sb.append(' ').append(StringUtils.join(data, ' '));
       397  0
                       } catch (MalformedURLException ex) {
       398  0
                           LOGGER.debug("error parsing {}", part, ex);
       399  0
                           sb.append(' ').append(part);
      -  400  19
                       }
      +  400  38
                       }
       401  
                   } else {
       402  0
                       sb.append(' ').append(part);
      @@ -721,13 +721,13 @@
                   }
       404  
               }
      -  405  19
               return sb.toString().trim();
      +  405  38
               return sb.toString().trim();
       406  
           }
       407  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Identifier.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Identifier.html index 41d7fcb82..13bfca30d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Identifier.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Identifier.html @@ -67,7 +67,7 @@
        * @author Jeremy Long
       25  
        */
      -  26  30
       public class Identifier implements Serializable, Comparable<Identifier> {
      +  26  62
       public class Identifier implements Serializable, Comparable<Identifier> {
       27  
       
       28   @@ -110,11 +110,11 @@
            * @param url the identifier url.
       48  
            */
      -  49  27
           public Identifier(String type, String value, String url) {
      -  50  27
               this.type = type;
      -  51  27
               this.value = value;
      -  52  27
               this.url = url;
      -  53  27
           }
      +  49  56
           public Identifier(String type, String value, String url) {
      +  50  56
               this.type = type;
      +  51  56
               this.value = value;
      +  52  56
               this.url = url;
      +  53  56
           }
       54  
       
       55   @@ -179,8 +179,8 @@
            */
       87  
           public void setConfidence(Confidence confidence) {
      -  88  5
               this.confidence = confidence;
      -  89  5
           }
      +  88  12
               this.confidence = confidence;
      +  89  12
           }
       90  
       
       91   @@ -205,7 +205,7 @@
            */
       101  
           public String getValue() {
      -  102  180
               return value;
      +  102  432
               return value;
       103  
           }
       104   @@ -287,7 +287,7 @@
            */
       145  
           public String getType() {
      -  146  288
               return type;
      +  146  744
               return type;
       147  
           }
       148   @@ -383,10 +383,10 @@
           @Override
       201  
           public int hashCode() {
      -  202  18
               int hash = 5;
      -  203  18
               hash = 53 * hash + (this.value != null ? this.value.hashCode() : 0);
      -  204  18
               hash = 53 * hash + (this.type != null ? this.type.hashCode() : 0);
      -  205  18
               return hash;
      +  202  36
               int hash = 5;
      +  203  36
               hash = 53 * hash + (this.value != null ? this.value.hashCode() : 0);
      +  204  36
               hash = 53 * hash + (this.type != null ? this.type.hashCode() : 0);
      +  205  36
               return hash;
       206  
           }
       207   @@ -426,17 +426,17 @@
           @Override
       225  
           public int compareTo(Identifier o) {
      -  226  32
               if (o == null) {
      +  226  66
               if (o == null) {
       227  0
                   return -1;
       228  
               }
      -  229  32
               return this.value.compareTo(o.value);
      +  229  66
               return this.value.compareTo(o.value);
       230  
           }
       231  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html index 9412df7ee..230e5e836 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      Reference
      38%
      13/34
      14%
      5/34
      3.444
      Reference
      37%
      13/35
      14%
      5/34
      3.2
       
      @@ -62,233 +62,244 @@  22  
       /**
       23   -
        * An external reference for a vulnerability. This contains a name, URL, and a source.
      +
        * An external reference for a vulnerability. This contains a name, URL, and a
       24   -
        *
      +
        * source.
       25   -
        * @author Jeremy Long
      +
        *
       26   +
        * @author Jeremy Long
      +  27  
        */
      -  27  500
       public class Reference implements Serializable, Comparable<Reference> {
      -  28   -
       
      +  28  1052
       public class Reference implements Serializable, Comparable<Reference> {
       29   -
           /**
      +
       
       30   -
            * the serial version uid.
      +
           /**
       31   -
            */
      +
            * the serial version uid.
       32   -
           private static final long serialVersionUID = -3444464824563008021L;
      +
            */
       33   -
           /**
      +
           private static final long serialVersionUID = -3444464824563008021L;
       34   -
            * The name of the reference.
      +
           /**
       35   -
            */
      +
            * The name of the reference.
       36   -
           private String name;
      +
            */
       37   -
       
      +
           private String name;
       38   -
           /**
      +
       
       39   -
            * Get the value of name.
      +
           /**
       40   -
            *
      +
            * Get the value of name.
       41   -
            * @return the value of name
      +
            *
       42   -
            */
      +
            * @return the value of name
       43   +
            */
      +  44  
           public String getName() {
      -  44  0
               return name;
      -  45   -
           }
      +  45  0
               return name;
       46   -
       
      +
           }
       47   -
           /**
      +
       
       48   -
            * Set the value of name.
      +
           /**
       49   -
            *
      +
            * Set the value of name.
       50   -
            * @param name new value of name
      +
            *
       51   -
            */
      +
            * @param name new value of name
       52   +
            */
      +  53  
           public void setName(String name) {
      -  53  156
               this.name = name;
      -  54  156
           }
      -  55   -
           /**
      +  54  326
               this.name = name;
      +  55  326
           }
       56   -
            * the url for the reference.
      +
           /**
       57   -
            */
      +
            * the url for the reference.
       58   -
           private String url;
      +
            */
       59   -
       
      +
           private String url;
       60   -
           /**
      +
       
       61   -
            * Get the value of url.
      +
           /**
       62   -
            *
      +
            * Get the value of url.
       63   -
            * @return the value of url
      +
            *
       64   -
            */
      +
            * @return the value of url
       65   +
            */
      +  66  
           public String getUrl() {
      -  66  0
               return url;
      -  67   -
           }
      +  67  0
               return url;
       68   -
       
      -  69   -
           /**
      -  70   -
            * Set the value of url.
      -  71   -
            *
      -  72   -
            * @param url new value of url
      -  73   -
            */
      -  74   -
           public void setUrl(String url) {
      -  75  156
               this.url = url;
      -  76  156
           }
      -  77   -
           /**
      -  78   -
            * the source of the reference.
      -  79   -
            */
      -  80   -
           private String source;
      -  81   -
       
      -  82   -
           /**
      -  83   -
            * Get the value of source.
      -  84   -
            *
      -  85   -
            * @return the value of source
      -  86   -
            */
      -  87   -
           public String getSource() {
      -  88  0
               return source;
      -  89  
           }
      -  90   +  69  
       
      -  91   +  70  
           /**
      -  92   -
            * Set the value of source.
      -  93   +  71   +
            * Set the value of url.
      +  72  
            *
      -  94   -
            * @param source new value of source
      -  95   +  73   +
            * @param url new value of url
      +  74  
            */
      -  96   -
           public void setSource(String source) {
      -  97  156
               this.source = source;
      -  98  156
           }
      -  99   +  75   +
           public void setUrl(String url) {
      +  76  326
               this.url = url;
      +  77  326
           }
      +  78   +
           /**
      +  79   +
            * the source of the reference.
      +  80   +
            */
      +  81   +
           private String source;
      +  82  
       
      +  83   +
           /**
      +  84   +
            * Get the value of source.
      +  85   +
            *
      +  86   +
            * @return the value of source
      +  87   +
            */
      +  88   +
           public String getSource() {
      +  89  0
               return source;
      +  90   +
           }
      +  91   +
       
      +  92   +
           /**
      +  93   +
            * Set the value of source.
      +  94   +
            *
      +  95   +
            * @param source new value of source
      +  96   +
            */
      +  97   +
           public void setSource(String source) {
      +  98  326
               this.source = source;
      +  99  326
           }
       100   -
           @Override
      +
       
       101   -
           public boolean equals(Object obj) {
      -  102  0
               if (obj == null) {
      -  103  0
                   return false;
      +
           @Override
      +  102   +
           public String toString() {
      +  103  0
               return "Reference: { name='" + this.name + "', url='" + this.url + "', source='" + this.source + "' }";
       104   -
               }
      -  105  0
               if (getClass() != obj.getClass()) {
      -  106  0
                   return false;
      +
           }
      +  105   +
       
      +  106   +
           @Override
       107   +
           public boolean equals(Object obj) {
      +  108  0
               if (obj == null) {
      +  109  0
                   return false;
      +  110  
               }
      -  108  0
               final Reference other = (Reference) obj;
      -  109  0
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
      -  110  0
                   return false;
      -  111   +  111  0
               if (getClass() != obj.getClass()) {
      +  112  0
                   return false;
      +  113  
               }
      -  112  0
               if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) {
      -  113  0
                   return false;
      -  114   -
               }
      -  115  0
               if ((this.source == null) ? (other.source != null) : !this.source.equals(other.source)) {
      +  114  0
               final Reference other = (Reference) obj;
      +  115  0
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
       116  0
                   return false;
       117  
               }
      -  118  0
               return true;
      -  119   -
           }
      +  118  0
               if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) {
      +  119  0
                   return false;
       120   -
       
      -  121   -
           @Override
      -  122   -
           public int hashCode() {
      -  123  0
               int hash = 5;
      -  124  0
               hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
      -  125  0
               hash = 67 * hash + (this.url != null ? this.url.hashCode() : 0);
      -  126  0
               hash = 67 * hash + (this.source != null ? this.source.hashCode() : 0);
      -  127  0
               return hash;
      -  128   -
           }
      -  129   -
       
      -  130   -
           /**
      -  131   -
            * Implementation of the comparable interface.
      -  132   -
            *
      -  133   -
            * @param o the Reference being compared
      -  134   -
            * @return an integer indicating the ordering of the two objects
      -  135   -
            */
      -  136   -
           @Override
      -  137   -
           public int compareTo(Reference o) {
      -  138  344
               if (source.equals(o.source)) {
      -  139  104
                   if (name.equals(o.name)) {
      -  140  34
                       if (url.equals(o.url)) {
      -  141  34
                           return 0; //they are equal
      -  142   -
                       } else {
      -  143  0
                           return url.compareTo(o.url);
      -  144   -
                       }
      -  145   -
                   } else {
      -  146  70
                       return name.compareTo(o.name);
      -  147   -
                   }
      -  148   -
               } else {
      -  149  240
                   return source.compareTo(o.source);
      -  150  
               }
      -  151   +  121  0
               if ((this.source == null) ? (other.source != null) : !this.source.equals(other.source)) {
      +  122  0
                   return false;
      +  123   +
               }
      +  124  0
               return true;
      +  125  
           }
      -  152   +  126   +
       
      +  127   +
           @Override
      +  128   +
           public int hashCode() {
      +  129  0
               int hash = 5;
      +  130  0
               hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
      +  131  0
               hash = 67 * hash + (this.url != null ? this.url.hashCode() : 0);
      +  132  0
               hash = 67 * hash + (this.source != null ? this.source.hashCode() : 0);
      +  133  0
               return hash;
      +  134   +
           }
      +  135   +
       
      +  136   +
           /**
      +  137   +
            * Implementation of the comparable interface.
      +  138   +
            *
      +  139   +
            * @param o the Reference being compared
      +  140   +
            * @return an integer indicating the ordering of the two objects
      +  141   +
            */
      +  142   +
           @Override
      +  143   +
           public int compareTo(Reference o) {
      +  144  726
               if (source.equals(o.source)) {
      +  145  210
                   if (name.equals(o.name)) {
      +  146  70
                       if (url.equals(o.url)) {
      +  147  70
                           return 0; //they are equal
      +  148   +
                       } else {
      +  149  0
                           return url.compareTo(o.url);
      +  150   +
                       }
      +  151   +
                   } else {
      +  152  140
                       return name.compareTo(o.name);
      +  153   +
                   }
      +  154   +
               } else {
      +  155  516
                   return source.compareTo(o.source);
      +  156   +
               }
      +  157   +
           }
      +  158  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html index b3282fe4a..911a6bfdc 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      Vulnerability
      64%
      48/74
      22%
      4/18
      1.278
      Vulnerability
      57%
      50/87
      22%
      5/22
      1.324
       
      @@ -64,777 +64,804 @@  23  
       import java.util.TreeSet;
       24   -
       
      +
       import java.util.Iterator;
       25   -
       /**
      +
       
       26   -
        * Contains the information about a vulnerability.
      +
       /**
       27   -
        *
      +
        * Contains the information about a vulnerability.
       28   -
        * @author Jeremy Long
      +
        *
       29   +
        * @author Jeremy Long
      +  30  
        */
      -  30  36
       public class Vulnerability implements Serializable, Comparable<Vulnerability> {
      -  31   -
       
      +  31  80
       public class Vulnerability implements Serializable, Comparable<Vulnerability> {
       32   -
           /**
      +
       
       33   -
            * The serial version uid.
      +
           /**
       34   -
            */
      +
            * The serial version uid.
       35   -
           private static final long serialVersionUID = 307319490326651052L;
      +
            */
       36   -
           /**
      +
           private static final long serialVersionUID = 307319490326651052L;
       37   -
            * The name of the vulnerability.
      +
       
       38   -
            */
      +
           /**
       39   -
           private String name;
      +
            * The name of the vulnerability.
       40   -
       
      +
            */
       41   -
           /**
      +
           private String name;
       42   -
            * Get the value of name.
      +
       
       43   -
            *
      +
           /**
       44   -
            * @return the value of name
      +
            * Get the value of name.
       45   -
            */
      +
            *
       46   -
           public String getName() {
      -  47  53
               return name;
      +
            * @return the value of name
      +  47   +
            */
       48   -
           }
      -  49   -
       
      +
           public String getName() {
      +  49  146
               return name;
       50   -
           /**
      +
           }
       51   -
            * Set the value of name.
      +
       
       52   -
            *
      +
           /**
       53   -
            * @param name new value of name
      +
            * Set the value of name.
       54   -
            */
      +
            *
       55   +
            * @param name new value of name
      +  56   +
            */
      +  57  
           public void setName(String name) {
      -  56  36
               this.name = name;
      -  57  36
           }
      -  58   -
           /**
      -  59   -
            * the description of the vulnerability.
      +  58  74
               this.name = name;
      +  59  74
           }
       60   -
            */
      +
           /**
       61   -
           private String description;
      +
            * the description of the vulnerability.
       62   -
       
      +
            */
       63   -
           /**
      +
           private String description;
       64   -
            * Get the value of description.
      +
       
       65   -
            *
      +
           /**
       66   -
            * @return the value of description
      +
            * Get the value of description.
       67   -
            */
      +
            *
       68   -
           public String getDescription() {
      -  69  0
               return description;
      +
            * @return the value of description
      +  69   +
            */
       70   -
           }
      -  71   -
       
      +
           public String getDescription() {
      +  71  0
               return description;
       72   -
           /**
      +
           }
       73   -
            * Set the value of description.
      +
       
       74   -
            *
      +
           /**
       75   -
            * @param description new value of description
      +
            * Set the value of description.
       76   -
            */
      +
            *
       77   +
            * @param description new value of description
      +  78   +
            */
      +  79  
           public void setDescription(String description) {
      -  78  35
               this.description = description;
      -  79  35
           }
      -  80   -
           /**
      -  81   -
            * References for this vulnerability.
      +  80  72
               this.description = description;
      +  81  72
           }
       82   -
            */
      -  83  36
           private SortedSet<Reference> references = new TreeSet<Reference>();
      +
           /**
      +  83   +
            * References for this vulnerability.
       84   -
       
      -  85   -
           /**
      +
            */
      +  85  80
           private SortedSet<Reference> references = new TreeSet<Reference>();
       86   -
            * Get the value of references.
      +
       
       87   -
            *
      +
           /**
       88   -
            * @return the value of references
      +
            * Get the value of references.
       89   -
            */
      +
            *
       90   -
           public Set<Reference> getReferences() {
      -  91  0
               return references;
      +
            * @return the value of references
      +  91   +
            */
       92   -
           }
      -  93   -
       
      +
           public Set<Reference> getReferences() {
      +  93  0
               return references;
       94   -
           /**
      +
           }
       95   -
            * Set the value of references.
      +
       
       96   -
            *
      +
           /**
       97   -
            * @param references new value of references
      +
            * Set the value of references.
       98   -
            */
      +
            *
       99   +
            * @param references new value of references
      +  100   +
            */
      +  101  
           public void setReferences(SortedSet<Reference> references) {
      -  100  0
               this.references = references;
      -  101  0
           }
      -  102   -
       
      -  103   -
           /**
      +  102  0
               this.references = references;
      +  103  0
           }
       104   -
            * Adds a reference to the references collection.
      +
       
       105   -
            *
      +
           /**
       106   -
            * @param ref a reference for the vulnerability
      +
            * Adds a reference to the references collection.
       107   -
            */
      +
            *
       108   +
            * @param ref a reference for the vulnerability
      +  109   +
            */
      +  110  
           public void addReference(Reference ref) {
      -  109  90
               this.references.add(ref);
      -  110  90
           }
      -  111   -
       
      -  112   -
           /**
      +  111  190
               this.references.add(ref);
      +  112  190
           }
       113   -
            * Adds a reference.
      +
       
       114   -
            *
      +
           /**
       115   -
            * @param referenceSource the source of the reference
      +
            * Adds a reference.
       116   -
            * @param referenceName the referenceName of the reference
      +
            *
       117   -
            * @param referenceUrl the url of the reference
      +
            * @param referenceSource the source of the reference
       118   -
            */
      +
            * @param referenceName the referenceName of the reference
       119   +
            * @param referenceUrl the url of the reference
      +  120   +
            */
      +  121  
           public void addReference(String referenceSource, String referenceName, String referenceUrl) {
      -  120  66
               final Reference ref = new Reference();
      -  121  66
               ref.setSource(referenceSource);
      -  122  66
               ref.setName(referenceName);
      -  123  66
               ref.setUrl(referenceUrl);
      -  124  66
               this.references.add(ref);
      -  125  66
           }
      -  126   -
           /**
      -  127   -
            * A set of vulnerable software.
      +  122  136
               final Reference ref = new Reference();
      +  123  136
               ref.setSource(referenceSource);
      +  124  136
               ref.setName(referenceName);
      +  125  136
               ref.setUrl(referenceUrl);
      +  126  136
               this.references.add(ref);
      +  127  136
           }
       128   -
            */
      -  129  36
           private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>();
      +
           /**
      +  129   +
            * A set of vulnerable software.
       130   -
       
      -  131   -
           /**
      +
            */
      +  131  80
           private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>();
       132   -
            * Get the value of vulnerableSoftware.
      +
       
       133   -
            *
      +
           /**
       134   -
            * @return the value of vulnerableSoftware
      +
            * Get the value of vulnerableSoftware.
       135   -
            */
      +
            *
       136   -
           public Set<VulnerableSoftware> getVulnerableSoftware() {
      -  137  0
               return vulnerableSoftware;
      +
            * @return the value of vulnerableSoftware
      +  137   +
            */
       138   -
           }
      -  139   -
       
      +
           public Set<VulnerableSoftware> getVulnerableSoftware() {
      +  139  6
               return vulnerableSoftware;
       140   -
           /**
      +
           }
       141   -
            * Set the value of vulnerableSoftware.
      +
       
       142   -
            *
      +
           /**
       143   -
            * @param vulnerableSoftware new value of vulnerableSoftware
      +
            * Set the value of vulnerableSoftware.
       144   -
            */
      +
            *
       145   +
            * @param vulnerableSoftware new value of vulnerableSoftware
      +  146   +
            */
      +  147  
           public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) {
      -  146  0
               this.vulnerableSoftware = vulnerableSoftware;
      -  147  0
           }
      -  148   -
       
      -  149   -
           /**
      +  148  0
               this.vulnerableSoftware = vulnerableSoftware;
      +  149  0
           }
       150   -
            * Adds an entry for vulnerable software.
      +
       
       151   -
            *
      +
           /**
       152   -
            * @param cpe string representation of a CPE entry
      -  153   -
            * @return if the add succeeded
      -  154   -
            */
      -  155   -
           public boolean addVulnerableSoftware(String cpe) {
      -  156  845
               return addVulnerableSoftware(cpe, null);
      -  157   -
           }
      -  158   -
       
      -  159   -
           /**
      -  160  
            * Adds an entry for vulnerable software.
      -  161   +  153  
            *
      -  162   -
            * @param cpe string representation of a cpe
      -  163   -
            * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable)
      -  164   +  154   +
            * @param cpe string representation of a CPE entry
      +  155  
            * @return if the add succeeded
      +  156   +
            */
      +  157   +
           public boolean addVulnerableSoftware(String cpe) {
      +  158  1752
               return addVulnerableSoftware(cpe, null);
      +  159   +
           }
      +  160   +
       
      +  161   +
           /**
      +  162   +
            * Adds an entry for vulnerable software.
      +  163   +
            *
      +  164   +
            * @param cpe string representation of a cpe
       165   -
            */
      +
            * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable)
       166   +
            * @return if the add succeeded
      +  167   +
            */
      +  168  
           public boolean addVulnerableSoftware(String cpe, String previousVersion) {
      -  167  853
               final VulnerableSoftware vs = new VulnerableSoftware();
      -  168  853
               vs.setCpe(cpe);
      -  169  853
               if (previousVersion != null) {
      -  170  8
                   vs.setPreviousVersion(previousVersion);
      -  171   -
               }
      -  172  853
               return updateVulnerableSoftware(vs);
      +  169  1894
               final VulnerableSoftware vs = new VulnerableSoftware();
      +  170  1894
               vs.setCpe(cpe);
      +  171  1894
               if (previousVersion != null) {
      +  172  18
                   vs.setPreviousVersion(previousVersion);
       173   -
           }
      -  174   -
       
      +
               }
      +  174  1894
               return updateVulnerableSoftware(vs);
       175   -
           /**
      +
           }
       176   -
            * Adds or updates a vulnerable software entry.
      +
       
       177   -
            *
      +
           /**
       178   -
            * @param vulnSoftware the vulnerable software
      +
            * Adds or updates a vulnerable software entry.
       179   -
            * @return if the update succeeded
      +
            *
       180   -
            */
      +
            * @param vulnSoftware the vulnerable software
       181   +
            * @return if the update succeeded
      +  182   +
            */
      +  183  
           public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) {
      -  182  853
               if (vulnerableSoftware.contains(vulnSoftware)) {
      -  183  0
                   vulnerableSoftware.remove(vulnSoftware);
      -  184   -
               }
      -  185  853
               return vulnerableSoftware.add(vulnSoftware);
      +  184  1896
               if (vulnerableSoftware.contains(vulnSoftware)) {
      +  185  6
                   vulnerableSoftware.remove(vulnSoftware);
       186   -
           }
      -  187   -
           /**
      +
               }
      +  187  1896
               return vulnerableSoftware.add(vulnSoftware);
       188   -
            * The CWE for the vulnerability.
      +
           }
       189   -
            */
      +
           /**
       190   -
           private String cwe;
      +
            * The CWE for the vulnerability.
       191   -
       
      +
            */
       192   -
           /**
      +
           private String cwe;
       193   -
            * Get the value of cwe.
      +
       
       194   -
            *
      +
           /**
       195   -
            * @return the value of cwe
      +
            * Get the value of cwe.
       196   -
            */
      +
            *
       197   -
           public String getCwe() {
      -  198  2
               return cwe;
      +
            * @return the value of cwe
      +  198   +
            */
       199   -
           }
      -  200   -
       
      +
           public String getCwe() {
      +  200  4
               return cwe;
       201   -
           /**
      +
           }
       202   -
            * Set the value of cwe.
      +
       
       203   -
            *
      +
           /**
       204   -
            * @param cwe new value of cwe
      +
            * Set the value of cwe.
       205   -
            */
      +
            *
       206   +
            * @param cwe new value of cwe
      +  207   +
            */
      +  208  
           public void setCwe(String cwe) {
      -  207  28
               this.cwe = cwe;
      -  208  28
           }
      -  209   -
           /**
      -  210   -
            * CVSS Score.
      +  209  58
               this.cwe = cwe;
      +  210  58
           }
       211   -
            */
      +
           /**
       212   -
           private float cvssScore;
      +
            * CVSS Score.
       213   -
       
      +
            */
       214   -
           /**
      +
           private float cvssScore;
       215   -
            * Get the value of cvssScore.
      +
       
       216   -
            *
      +
           /**
       217   -
            * @return the value of cvssScore
      +
            * Get the value of cvssScore.
       218   -
            */
      +
            *
       219   -
           public float getCvssScore() {
      -  220  3
               return cvssScore;
      +
            * @return the value of cvssScore
      +  220   +
            */
       221   -
           }
      -  222   -
       
      +
           public float getCvssScore() {
      +  222  6
               return cvssScore;
       223   -
           /**
      +
           }
       224   -
            * Set the value of cvssScore.
      +
       
       225   -
            *
      +
           /**
       226   -
            * @param cvssScore new value of cvssScore
      +
            * Set the value of cvssScore.
       227   -
            */
      +
            *
       228   +
            * @param cvssScore new value of cvssScore
      +  229   +
            */
      +  230  
           public void setCvssScore(float cvssScore) {
      -  229  35
               this.cvssScore = cvssScore;
      -  230  35
           }
      -  231   -
           /**
      -  232   -
            * CVSS Access Vector.
      +  231  72
               this.cvssScore = cvssScore;
      +  232  72
           }
       233   -
            */
      +
           /**
       234   -
           private String cvssAccessVector;
      +
            * CVSS Access Vector.
       235   -
       
      +
            */
       236   -
           /**
      +
           private String cvssAccessVector;
       237   -
            * Get the value of cvssAccessVector.
      +
       
       238   -
            *
      +
           /**
       239   -
            * @return the value of cvssAccessVector
      +
            * Get the value of cvssAccessVector.
       240   -
            */
      +
            *
       241   -
           public String getCvssAccessVector() {
      -  242  0
               return cvssAccessVector;
      +
            * @return the value of cvssAccessVector
      +  242   +
            */
       243   -
           }
      -  244   -
       
      +
           public String getCvssAccessVector() {
      +  244  0
               return cvssAccessVector;
       245   -
           /**
      +
           }
       246   -
            * Set the value of cvssAccessVector.
      +
       
       247   -
            *
      +
           /**
       248   -
            * @param cvssAccessVector new value of cvssAccessVector
      +
            * Set the value of cvssAccessVector.
       249   -
            */
      +
            *
       250   +
            * @param cvssAccessVector new value of cvssAccessVector
      +  251   +
            */
      +  252  
           public void setCvssAccessVector(String cvssAccessVector) {
      -  251  34
               this.cvssAccessVector = cvssAccessVector;
      -  252  34
           }
      -  253   -
           /**
      -  254   -
            * CVSS Access Complexity.
      +  253  70
               this.cvssAccessVector = cvssAccessVector;
      +  254  70
           }
       255   -
            */
      +
           /**
       256   -
           private String cvssAccessComplexity;
      +
            * CVSS Access Complexity.
       257   -
       
      +
            */
       258   -
           /**
      +
           private String cvssAccessComplexity;
       259   -
            * Get the value of cvssAccessComplexity.
      +
       
       260   -
            *
      +
           /**
       261   -
            * @return the value of cvssAccessComplexity
      +
            * Get the value of cvssAccessComplexity.
       262   -
            */
      +
            *
       263   -
           public String getCvssAccessComplexity() {
      -  264  0
               return cvssAccessComplexity;
      +
            * @return the value of cvssAccessComplexity
      +  264   +
            */
       265   -
           }
      -  266   -
       
      +
           public String getCvssAccessComplexity() {
      +  266  0
               return cvssAccessComplexity;
       267   -
           /**
      +
           }
       268   -
            * Set the value of cvssAccessComplexity.
      +
       
       269   -
            *
      +
           /**
       270   -
            * @param cvssAccessComplexity new value of cvssAccessComplexity
      +
            * Set the value of cvssAccessComplexity.
       271   -
            */
      +
            *
       272   +
            * @param cvssAccessComplexity new value of cvssAccessComplexity
      +  273   +
            */
      +  274  
           public void setCvssAccessComplexity(String cvssAccessComplexity) {
      -  273  34
               this.cvssAccessComplexity = cvssAccessComplexity;
      -  274  34
           }
      -  275   -
           /**
      -  276   -
            * CVSS Authentication.
      +  275  70
               this.cvssAccessComplexity = cvssAccessComplexity;
      +  276  70
           }
       277   -
            */
      +
           /**
       278   -
           private String cvssAuthentication;
      +
            * CVSS Authentication.
       279   -
       
      +
            */
       280   -
           /**
      +
           private String cvssAuthentication;
       281   -
            * Get the value of cvssAuthentication.
      +
       
       282   -
            *
      +
           /**
       283   -
            * @return the value of cvssAuthentication
      +
            * Get the value of cvssAuthentication.
       284   -
            */
      +
            *
       285   -
           public String getCvssAuthentication() {
      -  286  0
               return cvssAuthentication;
      +
            * @return the value of cvssAuthentication
      +  286   +
            */
       287   -
           }
      -  288   -
       
      +
           public String getCvssAuthentication() {
      +  288  0
               return cvssAuthentication;
       289   -
           /**
      +
           }
       290   -
            * Set the value of cvssAuthentication.
      +
       
       291   -
            *
      +
           /**
       292   -
            * @param cvssAuthentication new value of cvssAuthentication
      +
            * Set the value of cvssAuthentication.
       293   -
            */
      +
            *
       294   +
            * @param cvssAuthentication new value of cvssAuthentication
      +  295   +
            */
      +  296  
           public void setCvssAuthentication(String cvssAuthentication) {
      -  295  34
               this.cvssAuthentication = cvssAuthentication;
      -  296  34
           }
      -  297   -
           /**
      -  298   -
            * CVSS Confidentiality Impact.
      +  297  70
               this.cvssAuthentication = cvssAuthentication;
      +  298  70
           }
       299   -
            */
      +
           /**
       300   -
           private String cvssConfidentialityImpact;
      +
            * CVSS Confidentiality Impact.
       301   -
       
      +
            */
       302   -
           /**
      +
           private String cvssConfidentialityImpact;
       303   -
            * Get the value of cvssConfidentialityImpact.
      +
       
       304   -
            *
      +
           /**
       305   -
            * @return the value of cvssConfidentialityImpact
      +
            * Get the value of cvssConfidentialityImpact.
       306   -
            */
      +
            *
       307   -
           public String getCvssConfidentialityImpact() {
      -  308  0
               return cvssConfidentialityImpact;
      +
            * @return the value of cvssConfidentialityImpact
      +  308   +
            */
       309   -
           }
      -  310   -
       
      +
           public String getCvssConfidentialityImpact() {
      +  310  0
               return cvssConfidentialityImpact;
       311   -
           /**
      +
           }
       312   -
            * Set the value of cvssConfidentialityImpact.
      +
       
       313   -
            *
      +
           /**
       314   -
            * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact
      +
            * Set the value of cvssConfidentialityImpact.
       315   -
            */
      +
            *
       316   +
            * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact
      +  317   +
            */
      +  318  
           public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) {
      -  317  34
               this.cvssConfidentialityImpact = cvssConfidentialityImpact;
      -  318  34
           }
      -  319   -
           /**
      -  320   -
            * CVSS Integrity Impact.
      +  319  70
               this.cvssConfidentialityImpact = cvssConfidentialityImpact;
      +  320  70
           }
       321   -
            */
      +
           /**
       322   -
           private String cvssIntegrityImpact;
      +
            * CVSS Integrity Impact.
       323   -
       
      +
            */
       324   -
           /**
      +
           private String cvssIntegrityImpact;
       325   -
            * Get the value of cvssIntegrityImpact.
      +
       
       326   -
            *
      +
           /**
       327   -
            * @return the value of cvssIntegrityImpact
      +
            * Get the value of cvssIntegrityImpact.
       328   -
            */
      +
            *
       329   -
           public String getCvssIntegrityImpact() {
      -  330  0
               return cvssIntegrityImpact;
      +
            * @return the value of cvssIntegrityImpact
      +  330   +
            */
       331   -
           }
      -  332   -
       
      +
           public String getCvssIntegrityImpact() {
      +  332  0
               return cvssIntegrityImpact;
       333   -
           /**
      +
           }
       334   -
            * Set the value of cvssIntegrityImpact.
      +
       
       335   -
            *
      +
           /**
       336   -
            * @param cvssIntegrityImpact new value of cvssIntegrityImpact
      +
            * Set the value of cvssIntegrityImpact.
       337   -
            */
      +
            *
       338   +
            * @param cvssIntegrityImpact new value of cvssIntegrityImpact
      +  339   +
            */
      +  340  
           public void setCvssIntegrityImpact(String cvssIntegrityImpact) {
      -  339  34
               this.cvssIntegrityImpact = cvssIntegrityImpact;
      -  340  34
           }
      -  341   -
           /**
      -  342   -
            * CVSS Availability Impact.
      +  341  70
               this.cvssIntegrityImpact = cvssIntegrityImpact;
      +  342  70
           }
       343   -
            */
      +
           /**
       344   -
           private String cvssAvailabilityImpact;
      +
            * CVSS Availability Impact.
       345   -
       
      +
            */
       346   -
           /**
      +
           private String cvssAvailabilityImpact;
       347   -
            * Get the value of cvssAvailabilityImpact.
      +
       
       348   -
            *
      +
           /**
       349   -
            * @return the value of cvssAvailabilityImpact
      +
            * Get the value of cvssAvailabilityImpact.
       350   -
            */
      +
            *
       351   -
           public String getCvssAvailabilityImpact() {
      -  352  0
               return cvssAvailabilityImpact;
      +
            * @return the value of cvssAvailabilityImpact
      +  352   +
            */
       353   -
           }
      -  354   -
       
      +
           public String getCvssAvailabilityImpact() {
      +  354  0
               return cvssAvailabilityImpact;
       355   -
           /**
      +
           }
       356   -
            * Set the value of cvssAvailabilityImpact.
      +
       
       357   -
            *
      +
           /**
       358   -
            * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact
      +
            * Set the value of cvssAvailabilityImpact.
       359   -
            */
      +
            *
       360   +
            * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact
      +  361   +
            */
      +  362  
           public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) {
      -  361  34
               this.cvssAvailabilityImpact = cvssAvailabilityImpact;
      -  362  34
           }
      -  363   -
       
      -  364   -
           @Override
      +  363  70
               this.cvssAvailabilityImpact = cvssAvailabilityImpact;
      +  364  70
           }
       365   +
       
      +  366   +
           @Override
      +  367  
           public boolean equals(Object obj) {
      -  366  0
               if (obj == null) {
      -  367  0
                   return false;
      -  368   +  368  0
               if (obj == null) {
      +  369  0
                   return false;
      +  370  
               }
      -  369  0
               if (getClass() != obj.getClass()) {
      -  370  0
                   return false;
      -  371   +  371  0
               if (getClass() != obj.getClass()) {
      +  372  0
                   return false;
      +  373  
               }
      -  372  0
               final Vulnerability other = (Vulnerability) obj;
      -  373  0
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
      -  374  0
                   return false;
      -  375   -
               }
      -  376  0
               return true;
      +  374  0
               final Vulnerability other = (Vulnerability) obj;
      +  375  0
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
      +  376  0
                   return false;
       377   -
           }
      -  378   -
       
      +
               }
      +  378  0
               return true;
       379   -
           @Override
      +
           }
       380   -
           public int hashCode() {
      -  381  8
               int hash = 5;
      -  382  8
               hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0);
      -  383  8
               return hash;
      -  384   -
           }
      -  385  
       
      -  386   -
           /**
      -  387   -
            * Compares two vulnerabilities.
      -  388   -
            *
      -  389   -
            * @param v a vulnerability to be compared
      -  390   -
            * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than
      -  391   -
            * the specified vulnerability
      -  392   -
            */
      -  393   +  381  
           @Override
      -  394   -
           public int compareTo(Vulnerability v) {
      -  395  0
               return v.getName().compareTo(this.getName());
      -  396   +  382   +
           public int hashCode() {
      +  383  16
               int hash = 5;
      +  384  16
               hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0);
      +  385  16
               return hash;
      +  386  
           }
      +  387   +
       
      +  388   +
           @Override
      +  389   +
           public String toString() {
      +  390  0
               final StringBuilder sb = new StringBuilder("Vulnerability ");
      +  391  0
               sb.append(this.name);
      +  392  0
               sb.append("\nReferences:\n");
      +  393  0
               for (Iterator i = this.references.iterator(); i.hasNext();) {
      +  394  0
                 sb.append("=> ");
      +  395  0
                 sb.append(i.next());
      +  396  0
                 sb.append("\n");
       397   -
       
      -  398   -
           /**
      -  399   -
            * The CPE id that caused this vulnerability to be flagged.
      -  400   -
            */
      -  401   -
           private String matchedCPE;
      -  402   -
           /**
      +
               }
      +  398  0
               sb.append("\nSoftware:\n");
      +  399  0
               for (Iterator i = this.vulnerableSoftware.iterator(); i.hasNext();) {
      +  400  0
                 sb.append("=> ");
      +  401  0
                 sb.append(i.next());
      +  402  0
                 sb.append("\n");
       403   -
            * Whether or not all previous versions were affected.
      -  404   -
            */
      +
               }
      +  404  0
               return sb.toString();
       405   -
           private String matchedAllPreviousCPE;
      +
           }
       406   -
       
      +
           /**
       407   -
           /**
      +
            * Compares two vulnerabilities.
       408   -
            * Sets the CPE that caused this vulnerability to be flagged.
      +
            *
       409   -
            *
      +
            * @param v a vulnerability to be compared
       410   -
            * @param cpeId a CPE identifier
      +
            * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than
       411   -
            * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is
      +
            * the specified vulnerability
       412   -
            * considered true)
      +
            */
       413   -
            */
      +
           @Override
       414   -
           public void setMatchedCPE(String cpeId, String previous) {
      -  415  8
               matchedCPE = cpeId;
      -  416  8
               matchedAllPreviousCPE = previous;
      -  417  8
           }
      +
           public int compareTo(Vulnerability v) {
      +  415  0
               return v.getName().compareTo(this.getName());
      +  416   +
           }
      +  417   +
       
       418   -
       
      +
           /**
       419   -
           /**
      +
            * The CPE id that caused this vulnerability to be flagged.
       420   -
            * Get the value of matchedCPE.
      +
            */
       421   -
            *
      +
           private String matchedCPE;
       422   -
            * @return the value of matchedCPE
      +
           /**
       423   -
            */
      +
            * Whether or not all previous versions were affected.
       424   -
           public String getMatchedCPE() {
      -  425  0
               return matchedCPE;
      +
            */
      +  425   +
           private String matchedAllPreviousCPE;
       426   -
           }
      +
       
       427   -
       
      +
           /**
       428   -
           /**
      +
            * Sets the CPE that caused this vulnerability to be flagged.
       429   -
            * Get the value of matchedAllPreviousCPE.
      +
            *
       430   -
            *
      +
            * @param cpeId a CPE identifier
       431   -
            * @return the value of matchedAllPreviousCPE
      +
            * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is
       432   -
            */
      +
            * considered true)
       433   -
           public String getMatchedAllPreviousCPE() {
      -  434  0
               return matchedAllPreviousCPE;
      -  435   -
           }
      -  436   -
       
      -  437   -
           /**
      -  438   -
            * Determines whether or not matchedAllPreviousCPE has been set.
      -  439   -
            *
      -  440   -
            * @return true if matchedAllPreviousCPE is not null; otherwise false
      -  441  
            */
      +  434   +
           public void setMatchedCPE(String cpeId, String previous) {
      +  435  16
               matchedCPE = cpeId;
      +  436  16
               matchedAllPreviousCPE = previous;
      +  437  16
           }
      +  438   +
       
      +  439   +
           /**
      +  440   +
            * Get the value of matchedCPE.
      +  441   +
            *
       442   -
           public boolean hasMatchedAllPreviousCPE() {
      -  443  0
               return matchedAllPreviousCPE != null;
      +
            * @return the value of matchedCPE
      +  443   +
            */
       444   +
           public String getMatchedCPE() {
      +  445  0
               return matchedCPE;
      +  446  
           }
      -  445   +  447   +
       
      +  448   +
           /**
      +  449   +
            * Get the value of matchedAllPreviousCPE.
      +  450   +
            *
      +  451   +
            * @return the value of matchedAllPreviousCPE
      +  452   +
            */
      +  453   +
           public String getMatchedAllPreviousCPE() {
      +  454  0
               return matchedAllPreviousCPE;
      +  455   +
           }
      +  456   +
       
      +  457   +
           /**
      +  458   +
            * Determines whether or not matchedAllPreviousCPE has been set.
      +  459   +
            *
      +  460   +
            * @return true if matchedAllPreviousCPE is not null; otherwise false
      +  461   +
            */
      +  462   +
           public boolean hasMatchedAllPreviousCPE() {
      +  463  0
               return matchedAllPreviousCPE != null;
      +  464   +
           }
      +  465  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerabilityComparator.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerabilityComparator.html index 285da55aa..85c7cea2e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerabilityComparator.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerabilityComparator.html @@ -71,7 +71,7 @@
        * @author Jeremy Long
       27  
        */
      -  28  201
       public class VulnerabilityComparator implements Comparator<Vulnerability>, Serializable {
      +  28  418
       public class VulnerabilityComparator implements Comparator<Vulnerability>, Serializable {
       29  
       
       30   @@ -102,13 +102,13 @@
           @Override
       43  
           public int compare(Vulnerability o1, Vulnerability o2) {
      -  44  25
               return o2.getName().compareTo(o1.getName());
      +  44  50
               return o2.getName().compareTo(o1.getName());
       45  
           }
       46  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerableSoftware.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerableSoftware.html index 03f066d2f..800bf93a2 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerableSoftware.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerableSoftware.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      VulnerableSoftware
      68%
      68/99
      72%
      52/72
      3.15
      VulnerableSoftware
      70%
      70/99
      79%
      57/72
      3.15
       
      @@ -79,7 +79,7 @@
        * @author Jeremy Long
       31  
        */
      -  32  11521
       public class VulnerableSoftware extends IndexEntry implements Serializable, Comparable<VulnerableSoftware> {
      +  32  24636
       public class VulnerableSoftware extends IndexEntry implements Serializable, Comparable<VulnerableSoftware> {
       33  
       
       34   @@ -88,7 +88,7 @@
            * The logger.
       36  
            */
      -  37  1
           private static final Logger LOGGER = LoggerFactory.getLogger(VulnerableSoftware.class);
      +  37  2
           private static final Logger LOGGER = LoggerFactory.getLogger(VulnerableSoftware.class);
       38  
           /**
       39   @@ -113,13 +113,13 @@
           public void setCpe(String cpe) {
       49  
               try {
      -  50  970
                   parseName(cpe);
      +  50  2164
                   parseName(cpe);
       51  0
               } catch (UnsupportedEncodingException ex) {
       52  0
                   LOGGER.warn("Character encoding is unsupported for CPE '{}'.", cpe);
       53  0
                   LOGGER.debug("", ex);
       54  0
                   setName(cpe);
      -  55  970
               }
      -  56  970
           }
      +  55  2164
               }
      +  56  2164
           }
       57  
       
       58   @@ -154,32 +154,32 @@
           @Override
       73  
           public void parseName(String cpeName) throws UnsupportedEncodingException {
      -  74  1487
               this.name = cpeName;
      -  75  1487
               if (cpeName != null && cpeName.length() > 7) {
      -  76  1487
                   final String[] data = cpeName.substring(7).split(":");
      -  77  1487
                   if (data.length >= 1) {
      -  78  1487
                       this.setVendor(urlDecode(data[0]));
      +  74  3198
               this.name = cpeName;
      +  75  3198
               if (cpeName != null && cpeName.length() > 7) {
      +  76  3188
                   final String[] data = cpeName.substring(7).split(":");
      +  77  3188
                   if (data.length >= 1) {
      +  78  3188
                       this.setVendor(urlDecode(data[0]));
       79  
                   }
      -  80  1487
                   if (data.length >= 2) {
      -  81  1487
                       this.setProduct(urlDecode(data[1]));
      +  80  3188
                   if (data.length >= 2) {
      +  81  3186
                       this.setProduct(urlDecode(data[1]));
       82  
                   }
      -  83  1487
                   if (data.length >= 3) {
      -  84  1487
                       version = urlDecode(data[2]);
      +  83  3188
                   if (data.length >= 3) {
      +  84  3186
                       version = urlDecode(data[2]);
       85  
                   }
      -  86  1487
                   if (data.length >= 4) {
      -  87  232
                       update = urlDecode(data[3]);
      +  86  3188
                   if (data.length >= 4) {
      +  87  464
                       update = urlDecode(data[3]);
       88  
                   }
      -  89  1487
                   if (data.length >= 5) {
      +  89  3188
                   if (data.length >= 5) {
       90  0
                       edition = urlDecode(data[4]);
       91  
                   }
       92  
               }
      -  93  1487
           }
      +  93  3198
           }
       94  
           /**
       95   @@ -236,8 +236,8 @@
            */
       122  
           public void setPreviousVersion(String previousVersion) {
      -  123  9
               this.previousVersion = previousVersion;
      -  124  9
           }
      +  123  28
               this.previousVersion = previousVersion;
      +  124  28
           }
       125  
       
       126   @@ -256,20 +256,20 @@
           @Override
       133  
           public boolean equals(Object obj) {
      -  134  1
               if (obj == null) {
      +  134  8
               if (obj == null) {
       135  0
                   return false;
       136  
               }
      -  137  1
               if (getClass() != obj.getClass()) {
      +  137  8
               if (getClass() != obj.getClass()) {
       138  0
                   return false;
       139  
               }
      -  140  1
               final VulnerableSoftware other = (VulnerableSoftware) obj;
      -  141  1
               if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) {
      -  142  1
                   return false;
      +  140  8
               final VulnerableSoftware other = (VulnerableSoftware) obj;
      +  141  8
               if ((this.name == null) ? (other.getName() != null) : !this.name.equals(other.getName())) {
      +  142  2
                   return false;
       143  
               }
      -  144  0
               return true;
      +  144  6
               return true;
       145  
           }
       146   @@ -288,9 +288,9 @@
           @Override
       153  
           public int hashCode() {
      -  154  110
               int hash = 7;
      -  155  110
               hash = 83 * hash + (this.getName() != null ? this.getName().hashCode() : 0);
      -  156  110
               return hash;
      +  154  220
               int hash = 7;
      +  155  220
               hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
      +  156  220
               return hash;
       157  
           }
       158   @@ -309,7 +309,7 @@
           @Override
       165  
           public String toString() {
      -  166  0
               return "VulnerableSoftware{ name=" + name + ", previousVersion=" + previousVersion + '}';
      +  166  0
               return "VulnerableSoftware{" + name + "[" + previousVersion + "]}";
       167  
           }
       168   @@ -330,344 +330,326 @@
           @Override
       176  
           public int compareTo(VulnerableSoftware vs) {
      -  177  10036
               int result = 0;
      -  178  10036
               final String[] left = this.getName().split(":");
      -  179  10036
               final String[] right = vs.getName().split(":");
      -  180  10036
               final int max = (left.length <= right.length) ? left.length : right.length;
      -  181  10036
               if (max > 0) {
      -  182  60403
                   for (int i = 0; result == 0 && i < max; i++) {
      -  183  50367
                       final String[] subLeft = left[i].split("\\.");
      -  184  50367
                       final String[] subRight = right[i].split("\\.");
      -  185  50367
                       final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length;
      -  186  50367
                       if (subMax > 0) {
      -  187  114910
                           for (int x = 0; result == 0 && x < subMax; x++) {
      -  188  64543
                               if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) {
      +  177  21472
               int result = 0;
      +  178  21472
               final String[] left = this.name.split(":");
      +  179  21472
               final String[] right = vs.getName().split(":");
      +  180  21472
               final int max = (left.length <= right.length) ? left.length : right.length;
      +  181  21472
               if (max > 0) {
      +  182  129238
                   for (int i = 0; result == 0 && i < max; i++) {
      +  183  107766
                       final String[] subLeft = left[i].split("(\\.|-)");
      +  184  107766
                       final String[] subRight = right[i].split("(\\.|-)");
      +  185  107766
                       final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length;
      +  186  107766
                       if (subMax > 0) {
      +  187  246638
                           for (int x = 0; result == 0 && x < subMax; x++) {
      +  188  138890
                               if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) {
       189  
                                   try {
      -  190  23486
                                       result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x]));
      -  191   -
       //                                final long iLeft = Long.parseLong(subLeft[x]);
      +  190  51138
                                       result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x]));
      +  191  0
                                   } catch (NumberFormatException ex) {
       192   -
       //                                final long iRight = Long.parseLong(subRight[x]);
      -  193   -
       //                                if (iLeft != iRight) {
      -  194   -
       //                                    if (iLeft > iRight) {
      -  195   -
       //                                        result = 2;
      -  196   -
       //                                    } else {
      -  197   -
       //                                        result = -2;
      -  198   -
       //                                    }
      -  199   -
       //                                }
      -  200  0
                                   } catch (NumberFormatException ex) {
      -  201  
                                       //ignore the exception - they obviously aren't numbers
      -  202  0
                                       if (!subLeft[x].equalsIgnoreCase(subRight[x])) {
      -  203  0
                                           result = subLeft[x].compareToIgnoreCase(subRight[x]);
      -  204   +  193  0
                                       if (!subLeft[x].equalsIgnoreCase(subRight[x])) {
      +  194  0
                                           result = subLeft[x].compareToIgnoreCase(subRight[x]);
      +  195  
                                       }
      -  205  23486
                                   }
      -  206   +  196  51138
                                   }
      +  197  
                               } else {
      -  207  41057
                                   result = subLeft[x].compareToIgnoreCase(subRight[x]);
      +  198  87752
                                   result = subLeft[x].compareToIgnoreCase(subRight[x]);
      +  199   +
                               }
      +  200   +
                           }
      +  201  107748
                           if (result == 0) {
      +  202  86938
                               if (subLeft.length > subRight.length) {
      +  203  312
                                   result = 2;
      +  204   +
                               }
      +  205  86938
                               if (subRight.length > subLeft.length) {
      +  206  106
                                   result = -2;
      +  207   +
                               }
       208   -
                               }
      +
                           }
       209   -
                           }
      -  210  50367
                           if (result == 0) {
      -  211  40556
                               if (subLeft.length > subRight.length) {
      -  212  114
                                   result = 2;
      -  213   -
                               }
      -  214  40556
                               if (subRight.length > subLeft.length) {
      -  215  7
                                   result = -2;
      -  216   -
                               }
      -  217   -
                           }
      -  218  
                       } else {
      -  219  0
                           result = left[i].compareToIgnoreCase(right[i]);
      +  210  18
                           result = left[i].compareToIgnoreCase(right[i]);
      +  211   +
                       }
      +  212   +
                   }
      +  213  21472
                   if (result == 0) {
      +  214  232
                       if (left.length > right.length) {
      +  215  136
                           result = 2;
      +  216   +
                       }
      +  217  232
                       if (right.length > left.length) {
      +  218  20
                           result = -2;
      +  219   +
                       }
       220   -
                       }
      +
                   }
       221   -
                   }
      -  222  10036
                   if (result == 0) {
      -  223  104
                       if (left.length > right.length) {
      -  224  68
                           result = 2;
      -  225   -
                       }
      -  226  104
                       if (right.length > left.length) {
      -  227  10
                           result = -2;
      -  228   -
                       }
      -  229   -
                   }
      -  230  
               } else {
      -  231  0
                   result = this.getName().compareToIgnoreCase(vs.getName());
      -  232   +  222  0
                   result = this.getName().compareToIgnoreCase(vs.getName());
      +  223  
               }
      -  233  10036
               return result;
      -  234   +  224  21472
               return result;
      +  225  
           }
      -  235   +  226  
       
      -  236   +  227  
           /**
      -  237   +  228  
            * Determines if the string passed in is a positive integer.
      -  238   +  229  
            *
      -  239   +  230  
            * @param str the string to test
      -  240   +  231  
            * @return true if the string only contains 0-9, otherwise false.
      -  241   +  232  
            */
      -  242   +  233  
           private static boolean isPositiveInteger(final String str) {
      -  243  88101
               if (str == null || str.isEmpty()) {
      -  244  14
                   return false;
      -  245   +  234  190200
               if (str == null || str.isEmpty()) {
      +  235  28
                   return false;
      +  236  
               }
      -  246  143148
               for (int i = 0; i < str.length(); i++) {
      -  247  96104
                   final char c = str.charAt(i);
      -  248  96104
                   if (c < '0' || c > '9') {
      -  249  41043
                       return false;
      -  250   +  237  309718
               for (int i = 0; i < str.length(); i++) {
      +  238  207270
                   final char c = str.charAt(i);
      +  239  207270
                   if (c < '0' || c > '9') {
      +  240  87724
                       return false;
      +  241  
                   }
      -  251   +  242  
               }
      -  252  47044
               return true;
      -  253   +  243  102448
               return true;
      +  244  
           }
      -  254   +  245  
           /**
      -  255   +  246  
            * The name of the cpe.
      -  256   +  247  
            */
      -  257   +  248  
           private String name;
      +  249   +
       
      +  250   +
           /**
      +  251   +
            * Get the value of name.
      +  252   +
            *
      +  253   +
            * @return the value of name
      +  254   +
            */
      +  255   +
           public String getName() {
      +  256  21574
               return name;
      +  257   +
           }
       258  
       
       259  
           /**
       260   -
            * Get the value of name.
      +
            * Set the value of name.
       261  
            *
       262   -
            * @return the value of name
      +
            * @param name new value of name
       263  
            */
       264   -
           public String getName() {
      -  265  20311
               return name;
      -  266   -
           }
      -  267   -
       
      -  268   -
           /**
      -  269   -
            * Set the value of name.
      -  270   -
            *
      -  271   -
            * @param name new value of name
      -  272   -
            */
      -  273  
           public void setName(String name) {
      -  274  0
               this.name = name;
      -  275  0
           }
      -  276   +  265  0
               this.name = name;
      +  266  0
           }
      +  267  
           /**
      -  277   +  268  
            * The product version number.
      -  278   +  269  
            */
      -  279   +  270  
           private String version;
      +  271   +
       
      +  272   +
           /**
      +  273   +
            * Get the value of version.
      +  274   +
            *
      +  275   +
            * @return the value of version
      +  276   +
            */
      +  277   +
           public String getVersion() {
      +  278  3940
               return version;
      +  279   +
           }
       280  
       
       281  
           /**
       282   -
            * Get the value of version.
      +
            * Set the value of version.
       283  
            *
       284   -
            * @return the value of version
      +
            * @param version new value of version
       285  
            */
       286   -
           public String getVersion() {
      -  287  1969
               return version;
      -  288   -
           }
      -  289   -
       
      -  290   -
           /**
      -  291   -
            * Set the value of version.
      -  292   -
            *
      -  293   -
            * @param version new value of version
      -  294   -
            */
      -  295  
           public void setVersion(String version) {
      -  296  0
               this.version = version;
      -  297  0
           }
      -  298   +  287  0
               this.version = version;
      +  288  0
           }
      +  289  
           /**
      -  299   +  290  
            * The product update version.
      -  300   +  291  
            */
      -  301   +  292  
           private String update;
      +  293   +
       
      +  294   +
           /**
      +  295   +
            * Get the value of update.
      +  296   +
            *
      +  297   +
            * @return the value of update
      +  298   +
            */
      +  299   +
           public String getUpdate() {
      +  300  2858
               return update;
      +  301   +
           }
       302  
       
       303  
           /**
       304   -
            * Get the value of update.
      +
            * Set the value of update.
       305  
            *
       306   -
            * @return the value of update
      +
            * @param update new value of update
       307  
            */
       308   -
           public String getUpdate() {
      -  309  1429
               return update;
      -  310   -
           }
      -  311   -
       
      -  312   -
           /**
      -  313   -
            * Set the value of update.
      -  314   -
            *
      -  315   -
            * @param update new value of update
      -  316   -
            */
      -  317  
           public void setUpdate(String update) {
      -  318  0
               this.update = update;
      -  319  0
           }
      -  320   +  309  0
               this.update = update;
      +  310  0
           }
      +  311  
           /**
      -  321   +  312  
            * The product edition.
      -  322   +  313  
            */
      -  323   +  314  
           private String edition;
      +  315   +
       
      +  316   +
           /**
      +  317   +
            * Get the value of edition.
      +  318   +
            *
      +  319   +
            * @return the value of edition
      +  320   +
            */
      +  321   +
           public String getEdition() {
      +  322  0
               return edition;
      +  323   +
           }
       324  
       
       325  
           /**
       326   -
            * Get the value of edition.
      +
            * Set the value of edition.
       327  
            *
       328   -
            * @return the value of edition
      +
            * @param edition new value of edition
       329  
            */
       330   -
           public String getEdition() {
      -  331  0
               return edition;
      -  332   -
           }
      +
           public void setEdition(String edition) {
      +  331  0
               this.edition = edition;
      +  332  0
           }
       333  
       
       334  
           /**
       335   -
            * Set the value of edition.
      +
            * Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default.
       336  
            *
       337   -
            * @param edition new value of edition
      -  338   -
            */
      -  339   -
           public void setEdition(String edition) {
      -  340  0
               this.edition = edition;
      -  341  0
           }
      -  342   -
       
      -  343   -
           /**
      -  344   -
            * Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default.
      -  345   -
            *
      -  346  
            * @param string the string to URL Decode
      -  347   +  338  
            * @return the URL Decoded string
      -  348   +  339  
            */
      -  349   +  340  
           private String urlDecode(String string) {
      -  350  4693
               final String text = string.replace("+", "%2B");
      -  351   +  341  10024
               final String text = string.replace("+", "%2B");
      +  342  
               String result;
      -  352   +  343  
               try {
      -  353  4693
                   result = URLDecoder.decode(text, "UTF-8");
      -  354  0
               } catch (UnsupportedEncodingException ex) {
      -  355   +  344  10024
                   result = URLDecoder.decode(text, "UTF-8");
      +  345  0
               } catch (UnsupportedEncodingException ex) {
      +  346  
                   try {
      -  356  0
                       result = URLDecoder.decode(text, "ASCII");
      -  357  0
                   } catch (UnsupportedEncodingException ex1) {
      -  358  0
                       result = defaultUrlDecode(text);
      -  359  0
                   }
      -  360  4693
               }
      -  361  4693
               return result;
      -  362   +  347  0
                       result = URLDecoder.decode(text, "ASCII");
      +  348  0
                   } catch (UnsupportedEncodingException ex1) {
      +  349  0
                       result = defaultUrlDecode(text);
      +  350  0
                   }
      +  351  10024
               }
      +  352  10024
               return result;
      +  353  
           }
      -  363   +  354  
       
      -  364   +  355  
           /**
      -  365   +  356  
            * Call {@link java.net.URLDecoder#decode(String)} to URL decode using the default encoding.
      -  366   +  357  
            *
      -  367   +  358  
            * @param text www-form-encoded URL to decode
      -  368   +  359  
            * @return the newly decoded String
      -  369   +  360  
            */
      -  370   +  361  
           @SuppressWarnings("deprecation")
      -  371   +  362  
           private String defaultUrlDecode(final String text) {
      -  372  0
               return URLDecoder.decode(text);
      -  373   +  363  0
               return URLDecoder.decode(text);
      +  364  
           }
      -  374   +  365  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.NoDataException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.NoDataException.html index 61162b3b7..749283805 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.NoDataException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.NoDataException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ScanAgentException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ScanAgentException.html index f2a1eb661..4f2a6546e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ScanAgentException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ScanAgentException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html index 7c7cfef96..753c1158d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html @@ -170,6 +170,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html index f3c4d2a8f..9387d20cd 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html @@ -543,6 +543,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html index e60d244ae..ce1edeaed 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html @@ -235,6 +235,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.PropertyType.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.PropertyType.html index e5b4e3f40..90073f28c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.PropertyType.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.PropertyType.html @@ -71,7 +71,7 @@
        * @author Jeremy Long
       27  
        */
      -  28  571
       public class PropertyType {
      +  28  1976
       public class PropertyType {
       29  
       
       30   @@ -100,7 +100,7 @@
            */
       42  
           public String getValue() {
      -  43  82
               return value;
      +  43  236
               return value;
       44  
           }
       45   @@ -117,15 +117,15 @@
            */
       51  
           public void setValue(String value) {
      -  52  580
               this.value = value;
      -  53  580
           }
      +  52  1994
               this.value = value;
      +  53  1994
           }
       54  
           /**
       55  
            * Whether or not the expression is a regex.
       56  
            */
      -  57  571
           private boolean regex = false;
      +  57  1976
           private boolean regex = false;
       58  
       
       59   @@ -142,7 +142,7 @@
            */
       65  
           public boolean isRegex() {
      -  66  49
               return regex;
      +  66  134
               return regex;
       67  
           }
       68   @@ -161,15 +161,15 @@
            */
       75  
           public void setRegex(boolean value) {
      -  76  564
               this.regex = value;
      -  77  564
           }
      +  76  1962
               this.regex = value;
      +  77  1962
           }
       78  
           /**
       79  
            * Indicates case sensitivity.
       80  
            */
      -  81  571
           private boolean caseSensitive = false;
      +  81  1976
           private boolean caseSensitive = false;
       82  
       
       83   @@ -186,7 +186,7 @@
            */
       89  
           public boolean isCaseSensitive() {
      -  90  39
               return caseSensitive;
      +  90  114
               return caseSensitive;
       91  
           }
       92   @@ -205,8 +205,8 @@
            */
       99  
           public void setCaseSensitive(boolean value) {
      -  100  565
               this.caseSensitive = value;
      -  101  565
           }
      +  100  1964
               this.caseSensitive = value;
      +  101  1964
           }
       102  
           //</editor-fold>
       103   @@ -225,28 +225,28 @@
            */
       110  
           public boolean matches(String text) {
      -  111  82
               if (text == null) {
      +  111  288
               if (text == null) {
       112  0
                   return false;
       113  
               }
      -  114  82
               if (this.regex) {
      +  114  288
               if (this.regex) {
       115  
                   Pattern rx;
      -  116  36
                   if (this.caseSensitive) {
      -  117  2
                       rx = Pattern.compile(this.value);
      +  116  160
                   if (this.caseSensitive) {
      +  117  4
                       rx = Pattern.compile(this.value);
       118  
                   } else {
      -  119  34
                       rx = Pattern.compile(this.value, Pattern.CASE_INSENSITIVE);
      +  119  156
                       rx = Pattern.compile(this.value, Pattern.CASE_INSENSITIVE);
       120  
                   }
      -  121  36
                   return rx.matcher(text).matches();
      +  121  160
                   return rx.matcher(text).matches();
       122  
               } else {
      -  123  46
                   if (this.caseSensitive) {
      -  124  2
                       return value.equals(text);
      +  123  128
                   if (this.caseSensitive) {
      +  124  4
                       return value.equals(text);
       125  
                   } else {
      -  126  44
                       return value.equalsIgnoreCase(text);
      +  126  124
                       return value.equalsIgnoreCase(text);
       127  
                   }
       128   @@ -296,28 +296,28 @@
           @Override
       153  
           public boolean equals(Object obj) {
      -  154  1
               if (obj == null) {
      +  154  2
               if (obj == null) {
       155  0
                   return false;
       156  
               }
      -  157  1
               if (getClass() != obj.getClass()) {
      +  157  2
               if (getClass() != obj.getClass()) {
       158  0
                   return false;
       159  
               }
      -  160  1
               final PropertyType other = (PropertyType) obj;
      -  161  1
               if ((this.value == null) ? (other.value != null) : !this.value.equals(other.value)) {
      +  160  2
               final PropertyType other = (PropertyType) obj;
      +  161  2
               if ((this.value == null) ? (other.value != null) : !this.value.equals(other.value)) {
       162  0
                   return false;
       163  
               }
      -  164  1
               if (this.regex != other.regex) {
      +  164  2
               if (this.regex != other.regex) {
       165  0
                   return false;
       166  
               }
      -  167  1
               if (this.caseSensitive != other.caseSensitive) {
      +  167  2
               if (this.caseSensitive != other.caseSensitive) {
       168  0
                   return false;
       169  
               }
      -  170  1
               return true;
      +  170  2
               return true;
       171  
           }
       172   @@ -345,6 +345,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionErrorHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionErrorHandler.html index a55d24f28..8c5642f6a 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionErrorHandler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionErrorHandler.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      SuppressionErrorHandler
      11%
      2/17
      0%
      0/8
      2.5
      SuppressionErrorHandler
      82%
      14/17
      50%
      4/8
      2.5
       
      @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  9
       public class SuppressionErrorHandler implements ErrorHandler {
      +  31  28
       public class SuppressionErrorHandler implements ErrorHandler {
       32  
       
       33   @@ -86,7 +86,7 @@
            * The logger.
       35  
            */
      -  36  1
           private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class);
      +  36  2
           private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class);
       37  
       
       38   @@ -105,29 +105,29 @@
           private String getPrettyParseExceptionInfo(SAXParseException ex) {
       45  
       
      -  46  0
               final StringBuilder sb = new StringBuilder();
      +  46  6
               final StringBuilder sb = new StringBuilder();
       47  
       
      -  48  0
               if (ex.getSystemId() != null) {
      +  48  6
               if (ex.getSystemId() != null) {
       49  0
                   sb.append("systemId=").append(ex.getSystemId()).append(", ");
       50  
               }
      -  51  0
               if (ex.getPublicId() != null) {
      +  51  6
               if (ex.getPublicId() != null) {
       52  0
                   sb.append("publicId=").append(ex.getPublicId()).append(", ");
       53  
               }
      -  54  0
               if (ex.getLineNumber() > 0) {
      -  55  0
                   sb.append("Line=").append(ex.getLineNumber());
      +  54  6
               if (ex.getLineNumber() > 0) {
      +  55  6
                   sb.append("Line=").append(ex.getLineNumber());
       56  
               }
      -  57  0
               if (ex.getColumnNumber() > 0) {
      -  58  0
                   sb.append(", Column=").append(ex.getColumnNumber());
      +  57  6
               if (ex.getColumnNumber() > 0) {
      +  58  6
                   sb.append(", Column=").append(ex.getColumnNumber());
       59  
               }
      -  60  0
               sb.append(": ").append(ex.getMessage());
      +  60  6
               sb.append(": ").append(ex.getMessage());
       61  
       
      -  62  0
               return sb.toString();
      +  62  6
               return sb.toString();
       63  
           }
       64   @@ -148,8 +148,8 @@
           @Override
       72  
           public void warning(SAXParseException ex) throws SAXException {
      -  73  0
               LOGGER.debug("", ex);
      -  74  0
           }
      +  73  6
               LOGGER.debug("", ex);
      +  74  6
           }
       75  
       
       76   @@ -168,7 +168,7 @@
           @Override
       83  
           public void error(SAXParseException ex) throws SAXException {
      -  84  0
               throw new SAXException(getPrettyParseExceptionInfo(ex));
      +  84  6
               throw new SAXException(getPrettyParseExceptionInfo(ex));
       85  
           }
       86   @@ -196,6 +196,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionHandler.html index d97588ac5..1dd0f2988 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionHandler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionHandler.html @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  9
       public class SuppressionHandler extends DefaultHandler {
      +  31  28
       public class SuppressionHandler extends DefaultHandler {
       32  
       
       33   @@ -150,7 +150,7 @@
            * A list of suppression rules.
       67  
            */
      -  68  9
           private final List<SuppressionRule> suppressionRules = new ArrayList<SuppressionRule>();
      +  68  28
           private final List<SuppressionRule> suppressionRules = new ArrayList<SuppressionRule>();
       69  
       
       70   @@ -165,7 +165,7 @@
            */
       75  
           public List<SuppressionRule> getSuppressionRules() {
      -  76  9
               return suppressionRules;
      +  76  22
               return suppressionRules;
       77  
           }
       78   @@ -216,13 +216,13 @@
           @Override
       101  
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      -  102  1040
               currentAttributes = attributes;
      -  103  1040
               currentText = new StringBuilder();
      -  104  1040
               if (SUPPRESS.equals(qName)) {
      -  105  230
                   rule = new SuppressionRule();
      -  106  230
                   final String base = currentAttributes.getValue("base");
      -  107  230
                   if (base != null) {
      -  108  230
                       rule.setBase(Boolean.parseBoolean(base));
      +  102  3618
               currentAttributes = attributes;
      +  103  3618
               currentText = new StringBuilder();
      +  104  3618
               if (SUPPRESS.equals(qName)) {
      +  105  810
                   rule = new SuppressionRule();
      +  106  810
                   final String base = currentAttributes.getValue("base");
      +  107  810
                   if (base != null) {
      +  108  810
                       rule.setBase(Boolean.parseBoolean(base));
       109  
                   } else {
       110  0
                       rule.setBase(false);
      @@ -230,7 +230,7 @@
                   }
       112  
               }
      -  113  1040
           }
      +  113  3618
           }
       114  
       
       115   @@ -253,30 +253,30 @@
           @Override
       124  
           public void endElement(String uri, String localName, String qName) throws SAXException {
      -  125  1040
               if (SUPPRESS.equals(qName)) {
      -  126  230
                   suppressionRules.add(rule);
      -  127  230
                   rule = null;
      -  128  810
               } else if (FILE_PATH.equals(qName)) {
      -  129  47
                   final PropertyType pt = processPropertyType();
      -  130  47
                   rule.setFilePath(pt);
      -  131  47
               } else if (SHA1.equals(qName)) {
      -  132  4
                   rule.setSha1(currentText.toString());
      -  133  759
               } else if (GAV.equals(qName)) {
      -  134  175
                   final PropertyType pt = processPropertyType();
      -  135  175
                   rule.setGav(pt);
      -  136  175
               } else if (CPE.equals(qName)) {
      -  137  333
                   final PropertyType pt = processPropertyType();
      -  138  333
                   rule.addCpe(pt);
      -  139  333
               } else if (CWE.equals(qName)) {
      +  125  3618
               if (SUPPRESS.equals(qName)) {
      +  126  810
                   suppressionRules.add(rule);
      +  127  810
                   rule = null;
      +  128  2808
               } else if (FILE_PATH.equals(qName)) {
      +  129  150
                   final PropertyType pt = processPropertyType();
      +  130  150
                   rule.setFilePath(pt);
      +  131  150
               } else if (SHA1.equals(qName)) {
      +  132  8
                   rule.setSha1(currentText.toString());
      +  133  2650
               } else if (GAV.equals(qName)) {
      +  134  644
                   final PropertyType pt = processPropertyType();
      +  135  644
                   rule.setGav(pt);
      +  136  644
               } else if (CPE.equals(qName)) {
      +  137  1150
                   final PropertyType pt = processPropertyType();
      +  138  1150
                   rule.addCpe(pt);
      +  139  1150
               } else if (CWE.equals(qName)) {
       140  0
                   rule.addCwe(currentText.toString());
      -  141  251
               } else if (CVE.equals(qName)) {
      -  142  8
                   rule.addCve(currentText.toString());
      -  143  243
               } else if (CVSS_BELOW.equals(qName)) {
      -  144  4
                   final float cvss = Float.parseFloat(currentText.toString());
      -  145  4
                   rule.addCvssBelow(cvss);
      +  141  856
               } else if (CVE.equals(qName)) {
      +  142  16
                   rule.addCve(currentText.toString());
      +  143  840
               } else if (CVSS_BELOW.equals(qName)) {
      +  144  8
                   final float cvss = Float.parseFloat(currentText.toString());
      +  145  8
                   rule.addCvssBelow(cvss);
       146  
               }
      -  147  1040
           }
      +  147  3618
           }
       148  
       
       149   @@ -299,8 +299,8 @@
           @Override
       158  
           public void characters(char[] ch, int start, int length) throws SAXException {
      -  159  2346
               currentText.append(ch, start, length);
      -  160  2346
           }
      +  159  8178
               currentText.append(ch, start, length);
      +  160  8178
           }
       161  
       
       162   @@ -317,28 +317,28 @@
            */
       168  
           private PropertyType processPropertyType() {
      -  169  555
               final PropertyType pt = new PropertyType();
      -  170  555
               pt.setValue(currentText.toString());
      -  171  555
               if (currentAttributes != null && currentAttributes.getLength() > 0) {
      -  172  555
                   final String regex = currentAttributes.getValue("regex");
      -  173  555
                   if (regex != null) {
      -  174  555
                       pt.setRegex(Boolean.parseBoolean(regex));
      +  169  1944
               final PropertyType pt = new PropertyType();
      +  170  1944
               pt.setValue(currentText.toString());
      +  171  1944
               if (currentAttributes != null && currentAttributes.getLength() > 0) {
      +  172  1944
                   final String regex = currentAttributes.getValue("regex");
      +  173  1944
                   if (regex != null) {
      +  174  1944
                       pt.setRegex(Boolean.parseBoolean(regex));
       175  
                   }
      -  176  555
                   final String caseSensitive = currentAttributes.getValue("caseSensitive");
      -  177  555
                   if (caseSensitive != null) {
      -  178  555
                       pt.setCaseSensitive(Boolean.parseBoolean(caseSensitive));
      +  176  1944
                   final String caseSensitive = currentAttributes.getValue("caseSensitive");
      +  177  1944
                   if (caseSensitive != null) {
      +  178  1944
                       pt.setCaseSensitive(Boolean.parseBoolean(caseSensitive));
       179  
                   }
       180  
               }
      -  181  555
               return pt;
      +  181  1944
               return pt;
       182  
           }
       183  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParseException.html index 096936473..3ee3224f9 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParseException.html @@ -123,8 +123,8 @@
            */
       55  
           public SuppressionParseException(Throwable ex) {
      -  56  1
               super(ex);
      -  57  1
           }
      +  56  2
               super(ex);
      +  57  2
           }
       58  
       
       59   @@ -141,12 +141,12 @@
            */
       65  
           public SuppressionParseException(String msg, Throwable ex) {
      -  66  1
               super(msg, ex);
      -  67  1
           }
      +  66  2
               super(msg, ex);
      +  67  2
           }
       68  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParser.html index a1f550b7e..7adbee75a 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParser.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      SuppressionParser
      65%
      26/40
      50%
      1/2
      8
      SuppressionParser
      63%
      51/80
      50%
      3/6
      11.333
       
      @@ -101,7 +101,7 @@
        * @author Jeremy Long
       42  
        */
      -  43  6
       public class SuppressionParser {
      +  43  16
       public class SuppressionParser {
       44  
       
       45   @@ -110,135 +110,231 @@
            * The logger.
       47  
            */
      -  48  1
           private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class);
      +  48  2
           private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class);
       49  
           /**
       50   -
            * JAXP Schema Language. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
      +
            * JAXP Schema Language. Source:
       51   -
            */
      +
            * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
       52   -
           public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
      +
            */
       53   -
           /**
      +
           public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
       54   -
            * W3C XML Schema. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
      +
           /**
       55   -
            */
      +
            * W3C XML Schema. Source:
       56   -
           public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
      +
            * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
       57   -
           /**
      +
            */
       58   -
            * JAXP Schema Source. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
      +
           public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
       59   -
            */
      +
           /**
       60   -
           public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
      +
            * JAXP Schema Source. Source:
       61   -
       
      +
            * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
       62   -
           /**
      +
            */
       63   -
            * Parses the given xml file and returns a list of the suppression rules contained.
      +
           public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
       64   -
            *
      +
       
       65   -
            * @param file an xml file containing suppression rules
      -  66   -
            * @return a list of suppression rules
      -  67   -
            * @throws SuppressionParseException thrown if the xml file cannot be parsed
      -  68   -
            */
      -  69   -
           public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
      -  70  4
               FileInputStream fis = null;
      -  71   -
               try {
      -  72  4
                   fis = new FileInputStream(file);
      -  73  3
                   return parseSuppressionRules(fis);
      -  74  1
               } catch (IOException ex) {
      -  75  1
                   LOGGER.debug("", ex);
      -  76  1
                   throw new SuppressionParseException(ex);
      -  77   -
               } finally {
      -  78  4
                   if (fis != null) {
      -  79   -
                       try {
      -  80  3
                           fis.close();
      -  81  0
                       } catch (IOException ex) {
      -  82  0
                           LOGGER.debug("Unable to close stream", ex);
      -  83  7
                       }
      -  84   -
                   }
      -  85   -
               }
      -  86   -
           }
      -  87   -
       
      -  88  
           /**
      -  89   -
            * Parses the given xml stream and returns a list of the suppression rules contained.
      -  90   +  66   +
            * Parses the given xml file and returns a list of the suppression rules
      +  67   +
            * contained.
      +  68  
            *
      -  91   -
            * @param inputStream an InputStream containing suppression rues
      -  92   +  69   +
            * @param file an xml file containing suppression rules
      +  70  
            * @return a list of suppression rules
      -  93   -
            * @throws SuppressionParseException if the xml cannot be parsed
      -  94   +  71   +
            * @throws SuppressionParseException thrown if the xml file cannot be parsed
      +  72  
            */
      -  95   -
           public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException {
      -  96   +  73   +
           public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
      +  74  8
               FileInputStream fis = null;
      +  75  
               try {
      -  97  8
                   final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd");
      -  98  8
                   final SuppressionHandler handler = new SuppressionHandler();
      -  99  8
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
      -  100  8
                   factory.setNamespaceAware(true);
      -  101  8
                   factory.setValidating(true);
      -  102  8
                   final SAXParser saxParser = factory.newSAXParser();
      -  103  8
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
      -  104  8
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
      -  105  8
                   final XMLReader xmlReader = saxParser.getXMLReader();
      -  106  8
                   xmlReader.setErrorHandler(new SuppressionErrorHandler());
      -  107  8
                   xmlReader.setContentHandler(handler);
      -  108   -
       
      -  109  8
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
      -  110  8
                   final InputSource in = new InputSource(reader);
      -  111   -
                   //in.setEncoding("UTF-8");
      -  112   -
       
      -  113  8
                   xmlReader.parse(in);
      -  114   -
       
      -  115  8
                   return handler.getSuppressionRules();
      -  116  0
               } catch (ParserConfigurationException ex) {
      -  117  0
                   LOGGER.debug("", ex);
      -  118  0
                   throw new SuppressionParseException(ex);
      -  119  0
               } catch (SAXException ex) {
      -  120  0
                   LOGGER.debug("", ex);
      -  121  0
                   throw new SuppressionParseException(ex);
      -  122  0
               } catch (FileNotFoundException ex) {
      -  123  0
                   LOGGER.debug("", ex);
      -  124  0
                   throw new SuppressionParseException(ex);
      -  125  0
               } catch (IOException ex) {
      -  126  0
                   LOGGER.debug("", ex);
      -  127  0
                   throw new SuppressionParseException(ex);
      -  128   +  76  8
                   fis = new FileInputStream(file);
      +  77  6
                   return parseSuppressionRules(fis);
      +  78  2
               } catch (IOException ex) {
      +  79  2
                   LOGGER.debug("", ex);
      +  80  2
                   throw new SuppressionParseException(ex);
      +  81  6
               } catch (SAXException ex) {
      +  82   +
                   try {
      +  83  6
                       if (fis != null) {
      +  84   +
                           try {
      +  85  6
                               fis.close();
      +  86  0
                           } catch (IOException ex1) {
      +  87  0
                               LOGGER.debug("Unable to close stream", ex1);
      +  88  6
                           }
      +  89   +
                       }
      +  90  6
                       fis = new FileInputStream(file);
      +  91  0
                   } catch (FileNotFoundException ex1) {
      +  92  0
                       throw new SuppressionParseException(ex);
      +  93  6
                   }
      +  94  12
                   return parseOldSuppressionRules(fis);
      +  95   +
               } finally {
      +  96  8
                   if (fis != null) {
      +  97   +
                       try {
      +  98  6
                           fis.close();
      +  99  0
                       } catch (IOException ex) {
      +  100  0
                           LOGGER.debug("Unable to close stream", ex);
      +  101  8
                       }
      +  102   +
                   }
      +  103  
               }
      -  129   +  104  
           }
      -  130   +  105   +
       
      +  106   +
           /**
      +  107   +
            * Parses the given xml stream and returns a list of the suppression rules
      +  108   +
            * contained.
      +  109   +
            *
      +  110   +
            * @param inputStream an InputStream containing suppression rues
      +  111   +
            * @return a list of suppression rules
      +  112   +
            * @throws SuppressionParseException thrown if the xml cannot be parsed
      +  113   +
            * @throws SAXException thrown if the xml cannot be parsed
      +  114   +
            */
      +  115   +
           public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException {
      +  116   +
               try {
      +  117  20
                   final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/dependency-suppression.1.1.xsd");
      +  118  20
                   final SuppressionHandler handler = new SuppressionHandler();
      +  119  20
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
      +  120  20
                   factory.setNamespaceAware(true);
      +  121  20
                   factory.setValidating(true);
      +  122  20
                   final SAXParser saxParser = factory.newSAXParser();
      +  123  20
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
      +  124  20
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
      +  125  20
                   final XMLReader xmlReader = saxParser.getXMLReader();
      +  126  20
                   xmlReader.setErrorHandler(new SuppressionErrorHandler());
      +  127  20
                   xmlReader.setContentHandler(handler);
      +  128   +
       
      +  129  20
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
      +  130  20
                   final InputSource in = new InputSource(reader);
      +  131   +
                   //in.setEncoding("UTF-8");
      +  132   +
       
      +  133  20
                   xmlReader.parse(in);
      +  134   +
       
      +  135  14
                   return handler.getSuppressionRules();
      +  136  0
               } catch (ParserConfigurationException ex) {
      +  137  0
                   LOGGER.debug("", ex);
      +  138  0
                   throw new SuppressionParseException(ex);
      +  139  6
               } catch (SAXException ex) {
      +  140  6
                   if (ex.getMessage().contains("Cannot find the declaration of element 'suppressions'.")) {
      +  141  6
                       throw ex;
      +  142   +
                   } else {
      +  143  0
                       LOGGER.debug("", ex);
      +  144  0
                       throw new SuppressionParseException(ex);
      +  145   +
                   }
      +  146  0
               } catch (FileNotFoundException ex) {
      +  147  0
                   LOGGER.debug("", ex);
      +  148  0
                   throw new SuppressionParseException(ex);
      +  149  0
               } catch (IOException ex) {
      +  150  0
                   LOGGER.debug("", ex);
      +  151  0
                   throw new SuppressionParseException(ex);
      +  152   +
               }
      +  153   +
           }
      +  154   +
       
      +  155   +
           /**
      +  156   +
            * Parses the given xml stream and returns a list of the suppression rules
      +  157   +
            * contained.
      +  158   +
            *
      +  159   +
            * @param inputStream an InputStream containing suppression rues
      +  160   +
            * @return a list of suppression rules
      +  161   +
            * @throws SuppressionParseException if the xml cannot be parsed
      +  162   +
            */
      +  163   +
           private List<SuppressionRule> parseOldSuppressionRules(InputStream inputStream) throws SuppressionParseException {
      +  164   +
               try {
      +  165  6
                   final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd");
      +  166  6
                   final SuppressionHandler handler = new SuppressionHandler();
      +  167  6
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
      +  168  6
                   factory.setNamespaceAware(true);
      +  169  6
                   factory.setValidating(true);
      +  170  6
                   final SAXParser saxParser = factory.newSAXParser();
      +  171  6
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
      +  172  6
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
      +  173  6
                   final XMLReader xmlReader = saxParser.getXMLReader();
      +  174  6
                   xmlReader.setErrorHandler(new SuppressionErrorHandler());
      +  175  6
                   xmlReader.setContentHandler(handler);
      +  176   +
       
      +  177  6
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
      +  178  6
                   final InputSource in = new InputSource(reader);
      +  179   +
                   //in.setEncoding("UTF-8");
      +  180   +
       
      +  181  6
                   xmlReader.parse(in);
      +  182   +
       
      +  183  6
                   return handler.getSuppressionRules();
      +  184  0
               } catch (ParserConfigurationException ex) {
      +  185  0
                   LOGGER.debug("", ex);
      +  186  0
                   throw new SuppressionParseException(ex);
      +  187  0
               } catch (SAXException ex) {
      +  188  0
                   LOGGER.debug("", ex);
      +  189  0
                   throw new SuppressionParseException(ex);
      +  190  0
               } catch (FileNotFoundException ex) {
      +  191  0
                   LOGGER.debug("", ex);
      +  192  0
                   throw new SuppressionParseException(ex);
      +  193  0
               } catch (IOException ex) {
      +  194  0
                   LOGGER.debug("", ex);
      +  195  0
                   throw new SuppressionParseException(ex);
      +  196   +
               }
      +  197   +
           }
      +  198  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionRule.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionRule.html index 1f78a161f..6d55949b4 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionRule.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionRule.html @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  245
       public class SuppressionRule {
      +  31  840
       public class SuppressionRule {
       32  
       
       33   @@ -102,7 +102,7 @@
            */
       43  
           public PropertyType getFilePath() {
      -  44  1
               return filePath;
      +  44  2
               return filePath;
       45  
           }
       46   @@ -119,8 +119,8 @@
            */
       52  
           public void setFilePath(PropertyType filePath) {
      -  53  49
               this.filePath = filePath;
      -  54  49
           }
      +  53  154
               this.filePath = filePath;
      +  54  154
           }
       55  
           /**
       56   @@ -143,7 +143,7 @@
            */
       65  
           public String getSha1() {
      -  66  1
               return sha1;
      +  66  2
               return sha1;
       67  
           }
       68   @@ -160,15 +160,15 @@
            */
       74  
           public void setSha1(String sha1) {
      -  75  6
               this.sha1 = sha1;
      -  76  6
           }
      +  75  12
               this.sha1 = sha1;
      +  76  12
           }
       77  
           /**
       78  
            * A list of CPEs to suppression
       79  
            */
      -  80  245
           private List<PropertyType> cpe = new ArrayList<PropertyType>();
      +  80  840
           private List<PropertyType> cpe = new ArrayList<PropertyType>();
       81  
       
       82   @@ -183,7 +183,7 @@
            */
       87  
           public List<PropertyType> getCpe() {
      -  88  1
               return cpe;
      +  88  2
               return cpe;
       89  
           }
       90   @@ -200,8 +200,8 @@
            */
       96  
           public void setCpe(List<PropertyType> cpe) {
      -  97  1
               this.cpe = cpe;
      -  98  1
           }
      +  97  2
               this.cpe = cpe;
      +  98  2
           }
       99  
       
       100   @@ -216,8 +216,8 @@
            */
       105  
           public void addCpe(PropertyType cpe) {
      -  106  340
               this.cpe.add(cpe);
      -  107  340
           }
      +  106  1164
               this.cpe.add(cpe);
      +  107  1164
           }
       108  
       
       109   @@ -232,7 +232,7 @@
            */
       114  
           public boolean hasCpe() {
      -  115  27
               return !cpe.isEmpty();
      +  115  70
               return !cpe.isEmpty();
       116  
           }
       117   @@ -241,7 +241,7 @@
            * The list of cvssBelow scores.
       119  
            */
      -  120  245
           private List<Float> cvssBelow = new ArrayList<Float>();
      +  120  840
           private List<Float> cvssBelow = new ArrayList<Float>();
       121  
       
       122   @@ -256,7 +256,7 @@
            */
       127  
           public List<Float> getCvssBelow() {
      -  128  1
               return cvssBelow;
      +  128  2
               return cvssBelow;
       129  
           }
       130   @@ -273,8 +273,8 @@
            */
       136  
           public void setCvssBelow(List<Float> cvssBelow) {
      -  137  1
               this.cvssBelow = cvssBelow;
      -  138  1
           }
      +  137  2
               this.cvssBelow = cvssBelow;
      +  138  2
           }
       139  
       
       140   @@ -289,8 +289,8 @@
            */
       145  
           public void addCvssBelow(Float cvss) {
      -  146  7
               this.cvssBelow.add(cvss);
      -  147  7
           }
      +  146  14
               this.cvssBelow.add(cvss);
      +  147  14
           }
       148  
       
       149   @@ -305,7 +305,7 @@
            */
       154  
           public boolean hasCvssBelow() {
      -  155  24
               return !cvssBelow.isEmpty();
      +  155  64
               return !cvssBelow.isEmpty();
       156  
           }
       157   @@ -314,7 +314,7 @@
            * The list of cwe entries to suppress.
       159  
            */
      -  160  245
           private List<String> cwe = new ArrayList<String>();
      +  160  840
           private List<String> cwe = new ArrayList<String>();
       161  
       
       162   @@ -329,7 +329,7 @@
            */
       167  
           public List<String> getCwe() {
      -  168  1
               return cwe;
      +  168  2
               return cwe;
       169  
           }
       170   @@ -346,8 +346,8 @@
            */
       176  
           public void setCwe(List<String> cwe) {
      -  177  1
               this.cwe = cwe;
      -  178  1
           }
      +  177  2
               this.cwe = cwe;
      +  178  2
           }
       179  
       
       180   @@ -362,8 +362,8 @@
            */
       185  
           public void addCwe(String cwe) {
      -  186  2
               this.cwe.add(cwe);
      -  187  2
           }
      +  186  4
               this.cwe.add(cwe);
      +  187  4
           }
       188  
       
       189   @@ -378,7 +378,7 @@
            */
       194  
           public boolean hasCwe() {
      -  195  25
               return !cwe.isEmpty();
      +  195  66
               return !cwe.isEmpty();
       196  
           }
       197   @@ -387,7 +387,7 @@
            * The list of cve entries to suppress.
       199  
            */
      -  200  245
           private List<String> cve = new ArrayList<String>();
      +  200  840
           private List<String> cve = new ArrayList<String>();
       201  
       
       202   @@ -402,7 +402,7 @@
            */
       207  
           public List<String> getCve() {
      -  208  1
               return cve;
      +  208  2
               return cve;
       209  
           }
       210   @@ -419,8 +419,8 @@
            */
       216  
           public void setCve(List<String> cve) {
      -  217  1
               this.cve = cve;
      -  218  1
           }
      +  217  2
               this.cve = cve;
      +  218  2
           }
       219  
       
       220   @@ -435,8 +435,8 @@
            */
       225  
           public void addCve(String cve) {
      -  226  11
               this.cve.add(cve);
      -  227  11
           }
      +  226  22
               this.cve.add(cve);
      +  227  22
           }
       228  
       
       229   @@ -451,7 +451,7 @@
            */
       234  
           public boolean hasCve() {
      -  235  27
               return !cve.isEmpty();
      +  235  70
               return !cve.isEmpty();
       236  
           }
       237   @@ -460,7 +460,7 @@
            * A Maven GAV to suppression.
       239  
            */
      -  240  245
           private PropertyType gav = null;
      +  240  840
           private PropertyType gav = null;
       241  
       
       242   @@ -492,8 +492,8 @@
            */
       256  
           public void setGav(PropertyType gav) {
      -  257  176
               this.gav = gav;
      -  258  176
           }
      +  257  646
               this.gav = gav;
      +  258  646
           }
       259  
       
       260   @@ -537,7 +537,7 @@
            */
       280  
           public boolean isBase() {
      -  281  17
               return base;
      +  281  34
               return base;
       282  
           }
       283   @@ -554,8 +554,8 @@
            */
       289  
           public void setBase(boolean base) {
      -  290  232
               this.base = base;
      -  291  232
           }
      +  290  814
               this.base = base;
      +  291  814
           }
       292  
       
       293   @@ -572,71 +572,71 @@
            */
       299  
           public void process(Dependency dependency) {
      -  300  178
               if (filePath != null && !filePath.matches(dependency.getFilePath())) {
      -  301  12
                   return;
      +  300  900
               if (filePath != null && !filePath.matches(dependency.getFilePath())) {
      +  301  96
                   return;
       302  
               }
      -  303  166
               if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) {
      -  304  1
                   return;
      +  303  804
               if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) {
      +  304  2
                   return;
       305  
               }
      -  306  165
               if (gav != null) {
      -  307  141
                   final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
      -  308  141
                   boolean gavFound = false;
      -  309  355
                   while (itr.hasNext()) {
      -  310  215
                       final Identifier i = itr.next();
      -  311  215
                       if (identifierMatches("maven", this.gav, i)) {
      -  312  1
                           gavFound = true;
      -  313  1
                           break;
      +  306  802
               if (gav != null) {
      +  307  738
                   final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
      +  308  738
                   boolean gavFound = false;
      +  309  1298
                   while (itr.hasNext()) {
      +  310  562
                       final Identifier i = itr.next();
      +  311  562
                       if (identifierMatches("maven", this.gav, i)) {
      +  312  2
                           gavFound = true;
      +  313  2
                           break;
       314  
                       }
      -  315  214
                   }
      -  316  141
                   if (!gavFound) {
      -  317  140
                       return;
      +  315  560
                   }
      +  316  738
                   if (!gavFound) {
      +  317  736
                       return;
       318  
                   }
       319  
               }
       320  
       
      -  321  25
               if (this.hasCpe()) {
      -  322  20
                   final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
      -  323  54
                   while (itr.hasNext()) {
      -  324  34
                       final Identifier i = itr.next();
      -  325  34
                       for (PropertyType c : this.cpe) {
      -  326  42
                           if (identifierMatches("cpe", c, i)) {
      -  327  7
                               if (!isBase()) {
      -  328  4
                                   dependency.addSuppressedIdentifier(i);
      +  321  66
               if (this.hasCpe()) {
      +  322  56
                   final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
      +  323  148
                   while (itr.hasNext()) {
      +  324  92
                       final Identifier i = itr.next();
      +  325  92
                       for (PropertyType c : this.cpe) {
      +  326  120
                           if (identifierMatches("cpe", c, i)) {
      +  327  14
                               if (!isBase()) {
      +  328  8
                                   dependency.addSuppressedIdentifier(i);
       329  
                               }
      -  330  7
                               itr.remove();
      -  331  7
                               break;
      +  330  14
                               itr.remove();
      +  331  14
                               break;
       332  
                           }
      -  333  35
                       }
      -  334  34
                   }
      +  333  106
                       }
      +  334  92
                   }
       335  
               }
      -  336  25
               if (hasCve() || hasCwe() || hasCvssBelow()) {
      -  337  5
                   final Iterator<Vulnerability> itr = dependency.getVulnerabilities().iterator();
      -  338  10
                   while (itr.hasNext()) {
      -  339  5
                       boolean remove = false;
      -  340  5
                       final Vulnerability v = itr.next();
      -  341  5
                       for (String entry : this.cve) {
      -  342  3
                           if (entry.equalsIgnoreCase(v.getName())) {
      -  343  1
                               remove = true;
      -  344  1
                               break;
      +  336  66
               if (hasCve() || hasCwe() || hasCvssBelow()) {
      +  337  10
                   final Iterator<Vulnerability> itr = dependency.getVulnerabilities().iterator();
      +  338  20
                   while (itr.hasNext()) {
      +  339  10
                       boolean remove = false;
      +  340  10
                       final Vulnerability v = itr.next();
      +  341  10
                       for (String entry : this.cve) {
      +  342  6
                           if (entry.equalsIgnoreCase(v.getName())) {
      +  343  2
                               remove = true;
      +  344  2
                               break;
       345  
                           }
      -  346  2
                       }
      -  347  5
                       if (!remove) {
      -  348  4
                           for (String entry : this.cwe) {
      -  349  1
                               if (v.getCwe() != null) {
      -  350  1
                                   final String toMatch = String.format("CWE-%s ", entry);
      -  351  1
                                   final String toTest = v.getCwe().substring(0, toMatch.length()).toUpperCase();
      -  352  1
                                   if (toTest.equals(toMatch)) {
      -  353  1
                                       remove = true;
      -  354  1
                                       break;
      +  346  4
                       }
      +  347  10
                       if (!remove) {
      +  348  8
                           for (String entry : this.cwe) {
      +  349  2
                               if (v.getCwe() != null) {
      +  350  2
                                   final String toMatch = String.format("CWE-%s ", entry);
      +  351  2
                                   final String toTest = v.getCwe().substring(0, toMatch.length()).toUpperCase();
      +  352  2
                                   if (toTest.equals(toMatch)) {
      +  353  2
                                       remove = true;
      +  354  2
                                       break;
       355  
                                   }
       356   @@ -644,28 +644,28 @@  357  0
                           }
       358  
                       }
      -  359  5
                       if (!remove) {
      -  360  3
                           for (float cvss : this.cvssBelow) {
      -  361  3
                               if (v.getCvssScore() < cvss) {
      -  362  1
                                   remove = true;
      -  363  1
                                   break;
      +  359  10
                       if (!remove) {
      +  360  6
                           for (float cvss : this.cvssBelow) {
      +  361  6
                               if (v.getCvssScore() < cvss) {
      +  362  2
                                   remove = true;
      +  363  2
                                   break;
       364  
                               }
      -  365  2
                           }
      +  365  4
                           }
       366  
                       }
      -  367  5
                       if (remove) {
      -  368  3
                           if (!isBase()) {
      -  369  3
                               dependency.addSuppressedVulnerability(v);
      +  367  10
                       if (remove) {
      +  368  6
                           if (!isBase()) {
      +  369  6
                               dependency.addSuppressedVulnerability(v);
       370  
                           }
      -  371  3
                           itr.remove();
      +  371  6
                           itr.remove();
       372  
                       }
      -  373  5
                   }
      +  373  10
                   }
       374  
               }
      -  375  25
           }
      +  375  66
           }
       376  
       
       377   @@ -682,7 +682,7 @@
            */
       383  
           boolean cpeHasNoVersion(PropertyType c) {
      -  384  46
               return !c.isRegex() && countCharacter(c.getValue(), ':') <= 3;
      +  384  128
               return !c.isRegex() && countCharacter(c.getValue(), ':') <= 3;
       385  
           }
       386   @@ -703,14 +703,14 @@
            */
       394  
           int countCharacter(String str, char c) {
      -  395  44
               int count = 0;
      -  396  44
               int pos = str.indexOf(c) + 1;
      -  397  182
               while (pos > 0) {
      -  398  138
                   count += 1;
      -  399  138
                   pos = str.indexOf(c, pos) + 1;
      +  395  124
               int count = 0;
      +  396  124
               int pos = str.indexOf(c) + 1;
      +  397  508
               while (pos > 0) {
      +  398  384
                   count += 1;
      +  399  384
                   pos = str.indexOf(c, pos) + 1;
       400  
               }
      -  401  44
               return count;
      +  401  124
               return count;
       402  
           }
       403   @@ -733,24 +733,24 @@
            */
       412  
           boolean identifierMatches(String identifierType, PropertyType suppressionEntry, Identifier identifier) {
      -  413  266
               if (identifierType.equals(identifier.getType())) {
      -  414  49
                   if (suppressionEntry.matches(identifier.getValue())) {
      -  415  5
                       return true;
      -  416  44
                   } else if ("cpe".equals(identifierType) && cpeHasNoVersion(suppressionEntry)) {
      -  417  37
                       if (suppressionEntry.isCaseSensitive()) {
      +  413  700
               if (identifierType.equals(identifier.getType())) {
      +  414  134
                   if (suppressionEntry.matches(identifier.getValue())) {
      +  415  10
                       return true;
      +  416  124
                   } else if ("cpe".equals(identifierType) && cpeHasNoVersion(suppressionEntry)) {
      +  417  110
                       if (suppressionEntry.isCaseSensitive()) {
       418  0
                           return identifier.getValue().startsWith(suppressionEntry.getValue());
       419  
                       } else {
      -  420  37
                           final String id = identifier.getValue().toLowerCase();
      -  421  37
                           final String check = suppressionEntry.getValue().toLowerCase();
      -  422  37
                           return id.startsWith(check);
      +  420  110
                           final String id = identifier.getValue().toLowerCase();
      +  421  110
                           final String check = suppressionEntry.getValue().toLowerCase();
      +  422  110
                           return id.startsWith(check);
       423  
                       }
       424  
                   }
       425  
               }
      -  426  224
               return false;
      +  426  580
               return false;
       427  
           }
       428   @@ -823,6 +823,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html index c1d35cf31..8cecb0d61 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html @@ -89,7 +89,7 @@
            * The logger.
       36  
            */
      -  37  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DBUtils.class);
      +  37  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DBUtils.class);
       38  
       
       39   @@ -151,16 +151,16 @@
            */
       74  
           public static void closeStatement(Statement statement) {
      -  75  40
               if (statement != null) {
      +  75  98
               if (statement != null) {
       76  
                   try {
      -  77  40
                       statement.close();
      +  77  98
                       statement.close();
       78  0
                   } catch (SQLException ex) {
       79  0
                       LOGGER.trace(statement.toString(), ex);
      -  80  40
                   }
      +  80  98
                   }
       81  
               }
      -  82  40
           }
      +  82  98
           }
       83  
       
       84   @@ -175,20 +175,20 @@
            */
       89  
           public static void closeResultSet(ResultSet rs) {
      -  90  40
               if (rs != null) {
      +  90  98
               if (rs != null) {
       91  
                   try {
      -  92  40
                       rs.close();
      +  92  98
                       rs.close();
       93  0
                   } catch (SQLException ex) {
       94  0
                       LOGGER.trace(rs.toString(), ex);
      -  95  40
                   }
      +  95  98
                   }
       96  
               }
      -  97  40
           }
      +  97  98
           }
       98  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html index 11c37e398..2077721e4 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html @@ -101,14 +101,14 @@
           public static boolean withinDateRange(long date, long compareTo, int dayRange) {
       43  
               // ms = dayRange x 24 hours/day x 60 min/hour x 60 sec/min x 1000 ms/sec
      -  44  9
               final long msRange = dayRange * 24L * 60L * 60L * 1000L;
      -  45  9
               return (compareTo - date) < msRange;
      +  44  18
               final long msRange = dayRange * 24L * 60L * 60L * 1000L;
      +  45  18
               return (compareTo - date) < msRange;
       46  
           }
       47  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html index 27d9c7c42..2930e159e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html @@ -95,7 +95,7 @@
        * @author Jeremy Long
       39  
        */
      -  40  14
       public class DependencyVersion implements Iterable<String>, Comparable<DependencyVersion> {
      +  40  28
       public class DependencyVersion implements Iterable<String>, Comparable<DependencyVersion> {
       41  
       
       42   @@ -104,8 +104,8 @@
            * Constructor for a empty DependencyVersion.
       44  
            */
      -  45  4
           public DependencyVersion() {
      -  46  4
           }
      +  45  8
           public DependencyVersion() {
      +  46  8
           }
       47  
       
       48   @@ -122,9 +122,9 @@
            * @param version the well formatted version number to parse
       54  
            */
      -  55  1037
           public DependencyVersion(String version) {
      -  56  1037
               parseVersion(version);
      -  57  1037
           }
      +  55  2076
           public DependencyVersion(String version) {
      +  56  2076
               parseVersion(version);
      +  57  2076
           }
       58  
       
       59   @@ -141,21 +141,21 @@
            */
       65  
           public final void parseVersion(String version) {
      -  66  1039
               versionParts = new ArrayList<String>();
      -  67  1039
               if (version != null) {
      -  68  1039
                   final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
      -  69  1039
                   final Matcher matcher = rx.matcher(version.toLowerCase());
      -  70  4321
                   while (matcher.find()) {
      -  71  3282
                       versionParts.add(matcher.group());
      +  66  2080
               versionParts = new ArrayList<String>();
      +  67  2080
               if (version != null) {
      +  68  2080
                   final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
      +  69  2080
                   final Matcher matcher = rx.matcher(version.toLowerCase());
      +  70  8650
                   while (matcher.find()) {
      +  71  6570
                       versionParts.add(matcher.group());
       72  
                   }
      -  73  1039
                   if (versionParts.isEmpty()) {
      -  74  6
                       versionParts.add(version);
      +  73  2080
                   if (versionParts.isEmpty()) {
      +  74  12
                       versionParts.add(version);
       75  
                   }
       76  
               }
      -  77  1039
           }
      +  77  2080
           }
       78  
           /**
       79   @@ -178,7 +178,7 @@
            */
       88  
           public List<String> getVersionParts() {
      -  89  1813
               return versionParts;
      +  89  3630
               return versionParts;
       90  
           }
       91   @@ -195,8 +195,8 @@
            */
       97  
           public void setVersionParts(List<String> versionParts) {
      -  98  3
               this.versionParts = versionParts;
      -  99  3
           }
      +  98  6
               this.versionParts = versionParts;
      +  99  6
           }
       100  
       
       101   @@ -213,7 +213,7 @@
           @Override
       107  
           public Iterator<String> iterator() {
      -  108  1
               return versionParts.iterator();
      +  108  2
               return versionParts.iterator();
       109  
           }
       110   @@ -232,7 +232,7 @@
           @Override
       117  
           public String toString() {
      -  118  317
               return StringUtils.join(versionParts, '.');
      +  118  636
               return StringUtils.join(versionParts, '.');
       119  
           }
       120   @@ -253,29 +253,29 @@
           @Override
       128  
           public boolean equals(Object obj) {
      -  129  666
               if (obj == null) {
      +  129  1332
               if (obj == null) {
       130  0
                   return false;
       131  
               }
      -  132  666
               if (getClass() != obj.getClass()) {
      +  132  1332
               if (getClass() != obj.getClass()) {
       133  0
                   return false;
       134  
               }
      -  135  666
               final DependencyVersion other = (DependencyVersion) obj;
      -  136  666
               final int max = (this.versionParts.size() < other.versionParts.size())
      -  137  127
                       ? this.versionParts.size() : other.versionParts.size();
      +  135  1332
               final DependencyVersion other = (DependencyVersion) obj;
      +  136  1332
               final int max = (this.versionParts.size() < other.versionParts.size())
      +  137  254
                       ? this.versionParts.size() : other.versionParts.size();
       138  
               //TODO steal better version of code from compareTo
      -  139  1450
               for (int i = 0; i < max; i++) {
      -  140  1333
                   final String thisPart = this.versionParts.get(i);
      -  141  1333
                   final String otherPart = other.versionParts.get(i);
      -  142  1333
                   if (!thisPart.equals(otherPart)) {
      -  143  549
                       return false;
      +  139  2900
               for (int i = 0; i < max; i++) {
      +  140  2666
                   final String thisPart = this.versionParts.get(i);
      +  141  2666
                   final String otherPart = other.versionParts.get(i);
      +  142  2666
                   if (!thisPart.equals(otherPart)) {
      +  143  1098
                       return false;
       144  
                   }
       145  
               }
      -  146  117
               if (this.versionParts.size() > max) {
      +  146  234
               if (this.versionParts.size() > max) {
       147  0
                   for (int i = max; i < this.versionParts.size(); i++) {
       148  0
                       if (!"0".equals(this.versionParts.get(i))) {
       149  0
                           return false;
      @@ -287,10 +287,10 @@
               }
       153  
       
      -  154  117
               if (other.versionParts.size() > max) {
      -  155  93
                   for (int i = max; i < other.versionParts.size(); i++) {
      -  156  93
                       if (!"0".equals(other.versionParts.get(i))) {
      -  157  93
                           return false;
      +  154  234
               if (other.versionParts.size() > max) {
      +  155  186
                   for (int i = max; i < other.versionParts.size(); i++) {
      +  156  186
                       if (!"0".equals(other.versionParts.get(i))) {
      +  157  186
                           return false;
       158  
                       }
       159   @@ -309,7 +309,7 @@
                *  }
       166  
                */
      -  167  24
               return true;
      +  167  48
               return true;
       168  
           }
       169   @@ -328,9 +328,9 @@
           @Override
       176  
           public int hashCode() {
      -  177  1
               int hash = 5;
      -  178  1
               hash = 71 * hash + (this.versionParts != null ? this.versionParts.hashCode() : 0);
      -  179  1
               return hash;
      +  177  2
               int hash = 5;
      +  178  2
               hash = 71 * hash + (this.versionParts != null ? this.versionParts.hashCode() : 0);
      +  179  2
               return hash;
       180  
           }
       181   @@ -351,40 +351,40 @@
            */
       189  
           public boolean matchesAtLeastThreeLevels(DependencyVersion version) {
      -  190  424
               if (version == null) {
      +  190  848
               if (version == null) {
       191  0
                   return false;
       192  
               }
      -  193  424
               if (Math.abs(this.versionParts.size() - version.versionParts.size()) >= 3) {
      -  194  1
                   return false;
      +  193  848
               if (Math.abs(this.versionParts.size() - version.versionParts.size()) >= 3) {
      +  194  2
                   return false;
       195  
               }
       196  
       
      -  197  423
               final int max = (this.versionParts.size() < version.versionParts.size())
      -  198  88
                       ? this.versionParts.size() : version.versionParts.size();
      +  197  846
               final int max = (this.versionParts.size() < version.versionParts.size())
      +  198  176
                       ? this.versionParts.size() : version.versionParts.size();
       199  
       
      -  200  423
               boolean ret = true;
      -  201  872
               for (int i = 0; i < max; i++) {
      -  202  806
                   final String thisVersion = this.versionParts.get(i);
      -  203  806
                   final String otherVersion = version.getVersionParts().get(i);
      -  204  806
                   if (i >= 3) {
      -  205  2
                       if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
      -  206  1
                           ret = false;
      -  207  1
                           break;
      +  200  846
               boolean ret = true;
      +  201  1744
               for (int i = 0; i < max; i++) {
      +  202  1612
                   final String thisVersion = this.versionParts.get(i);
      +  203  1612
                   final String otherVersion = version.getVersionParts().get(i);
      +  204  1612
                   if (i >= 3) {
      +  205  4
                       if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
      +  206  2
                           ret = false;
      +  207  2
                           break;
       208  
                       }
      -  209  804
                   } else if (!thisVersion.equals(otherVersion)) {
      -  210  356
                       ret = false;
      -  211  356
                       break;
      +  209  1608
                   } else if (!thisVersion.equals(otherVersion)) {
      +  210  712
                       ret = false;
      +  211  712
                       break;
       212  
                   }
       213  
               }
       214  
       
      -  215  423
               return ret;
      +  215  846
               return ret;
       216  
           }
       217   @@ -393,50 +393,50 @@
           @Override
       219  
           public int compareTo(DependencyVersion version) {
      -  220  32
               if (version == null) {
      +  220  64
               if (version == null) {
       221  0
                   return 1;
       222  
               }
      -  223  32
               final List<String> left = this.getVersionParts();
      -  224  32
               final List<String> right = version.getVersionParts();
      -  225  32
               final int max = left.size() < right.size() ? left.size() : right.size();
      +  223  64
               final List<String> left = this.getVersionParts();
      +  224  64
               final List<String> right = version.getVersionParts();
      +  225  64
               final int max = left.size() < right.size() ? left.size() : right.size();
       226  
       
      -  227  82
               for (int i = 0; i < max; i++) {
      -  228  70
                   final String lStr = left.get(i);
      -  229  70
                   final String rStr = right.get(i);
      -  230  70
                   if (lStr.equals(rStr)) {
      -  231  50
                       continue;
      +  227  164
               for (int i = 0; i < max; i++) {
      +  228  140
                   final String lStr = left.get(i);
      +  229  140
                   final String rStr = right.get(i);
      +  230  140
                   if (lStr.equals(rStr)) {
      +  231  100
                       continue;
       232  
                   }
       233  
                   try {
      -  234  20
                       final int l = Integer.parseInt(lStr);
      -  235  13
                       final int r = Integer.parseInt(rStr);
      -  236  12
                       if (l < r) {
      -  237  9
                           return -1;
      -  238  3
                       } else if (l > r) {
      -  239  3
                           return 1;
      +  234  40
                       final int l = Integer.parseInt(lStr);
      +  235  26
                       final int r = Integer.parseInt(rStr);
      +  236  24
                       if (l < r) {
      +  237  18
                           return -1;
      +  238  6
                       } else if (l > r) {
      +  239  6
                           return 1;
       240  
                       }
      -  241  8
                   } catch (NumberFormatException ex) {
      -  242  8
                       final int comp = left.get(i).compareTo(right.get(i));
      -  243  8
                       if (comp < 0) {
      -  244  6
                           return -1;
      -  245  2
                       } else if (comp > 0) {
      -  246  2
                           return 1;
      +  241  16
                   } catch (NumberFormatException ex) {
      +  242  16
                       final int comp = left.get(i).compareTo(right.get(i));
      +  243  16
                       if (comp < 0) {
      +  244  12
                           return -1;
      +  245  4
                       } else if (comp > 0) {
      +  246  4
                           return 1;
       247  
                       }
       248  0
                   }
       249  
               }
      -  250  12
               if (left.size() < right.size()) {
      -  251  3
                   return -1;
      -  252  9
               } else if (left.size() > right.size()) {
      -  253  3
                   return 1;
      +  250  24
               if (left.size() < right.size()) {
      +  251  6
                   return -1;
      +  252  18
               } else if (left.size() > right.size()) {
      +  253  6
                   return 1;
       254  
               } else {
      -  255  6
                   return 0;
      +  255  12
                   return 0;
       256  
               }
       257   @@ -445,6 +445,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersionUtil.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersionUtil.html index d8861576d..aad346724 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersionUtil.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersionUtil.html @@ -87,7 +87,7 @@
            * Regular expression to extract version numbers from file names.
       35  
            */
      -  36  1
           private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha|\\d+)|[a-zA-Z_-]{1,3}\\d{0,8}))?");
      +  36  2
           private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha|\\d+)|[a-zA-Z_-]{1,3}\\d{0,8}))?");
       37  
           /**
       38   @@ -96,7 +96,7 @@
            * are missing a version number using the previous regex.
       40  
            */
      -  41  1
           private static final Pattern RX_SINGLE_VERSION = Pattern.compile("\\d+(\\.?([_-](release|beta|alpha)|[a-zA-Z_-]{1,3}\\d{1,8}))?");
      +  41  2
           private static final Pattern RX_SINGLE_VERSION = Pattern.compile("\\d+(\\.?([_-](release|beta|alpha)|[a-zA-Z_-]{1,3}\\d{1,8}))?");
       42  
       
       43   @@ -133,60 +133,60 @@
            */
       60  
           public static DependencyVersion parseVersion(String text) {
      -  61  987
               if (text == null) {
      +  61  1978
               if (text == null) {
       62  0
                   return null;
       63  
               }
       64  
               //'-' is a special case used within the CVE entries, just include it as the version.
      -  65  987
               if ("-".equals(text)) {
      -  66  1
                   final DependencyVersion dv = new DependencyVersion();
      -  67  1
                   final List<String> list = new ArrayList<String>();
      -  68  1
                   list.add(text);
      -  69  1
                   dv.setVersionParts(list);
      -  70  1
                   return dv;
      +  65  1978
               if ("-".equals(text)) {
      +  66  2
                   final DependencyVersion dv = new DependencyVersion();
      +  67  2
                   final List<String> list = new ArrayList<String>();
      +  68  2
                   list.add(text);
      +  69  2
                   dv.setVersionParts(list);
      +  70  2
                   return dv;
       71  
               }
      -  72  986
               String version = null;
      -  73  986
               Matcher matcher = RX_VERSION.matcher(text);
      -  74  986
               if (matcher.find()) {
      -  75  982
                   version = matcher.group();
      +  72  1976
               String version = null;
      +  73  1976
               Matcher matcher = RX_VERSION.matcher(text);
      +  74  1976
               if (matcher.find()) {
      +  75  1966
                   version = matcher.group();
       76  
               }
       77  
               //throw away the results if there are two things that look like version numbers
      -  78  986
               if (matcher.find()) {
      -  79  2
                   return null;
      +  78  1976
               if (matcher.find()) {
      +  79  4
                   return null;
       80  
               }
      -  81  984
               if (version == null) {
      -  82  4
                   matcher = RX_SINGLE_VERSION.matcher(text);
      -  83  4
                   if (matcher.find()) {
      -  84  2
                       version = matcher.group();
      +  81  1972
               if (version == null) {
      +  82  10
                   matcher = RX_SINGLE_VERSION.matcher(text);
      +  83  10
                   if (matcher.find()) {
      +  84  4
                       version = matcher.group();
       85  
                   } else {
      -  86  2
                       return null;
      +  86  6
                       return null;
       87  
                   }
       88  
                   //throw away the results if there are two things that look like version numbers
      -  89  2
                   if (matcher.find()) {
      -  90  1
                       return null;
      +  89  4
                   if (matcher.find()) {
      +  90  2
                       return null;
       91  
                   }
       92  
               }
      -  93  981
               if (version != null && version.endsWith("-py2") && version.length() > 4) {
      -  94  1
                   version = version.substring(0, version.length() - 4);
      +  93  1964
               if (version != null && version.endsWith("-py2") && version.length() > 4) {
      +  94  2
                   version = version.substring(0, version.length() - 4);
       95  
               }
      -  96  981
               return new DependencyVersion(version);
      +  96  1964
               return new DependencyVersion(version);
       97  
           }
       98  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html index abb857d6d..d8a47f75d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html @@ -117,7 +117,7 @@
            * The logger.
       50  
            */
      -  51  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ExtractionUtil.class);
      +  51  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ExtractionUtil.class);
       52  
       
       53   @@ -256,23 +256,23 @@
           public static void extractFilesUsingFilter(File archive, File destination,
       142  
                   FilenameFilter filter) throws ExtractionException {
      -  143  3
               if (archive == null || destination == null) {
      +  143  6
               if (archive == null || destination == null) {
       144  0
                   return;
       145  
               }
       146  
       
      -  147  3
               FileInputStream fis = null;
      +  147  6
               FileInputStream fis = null;
       148  
               try {
      -  149  3
                   fis = new FileInputStream(archive);
      +  149  6
                   fis = new FileInputStream(archive);
       150  0
               } catch (FileNotFoundException ex) {
       151  0
                   LOGGER.debug("", ex);
       152  0
                   throw new ExtractionException("Archive file was not found.", ex);
      -  153  3
               }
      +  153  6
               }
       154  
               try {
      -  155  3
                   extractArchive(new ZipArchiveInputStream(new BufferedInputStream(
      +  155  6
                   extractArchive(new ZipArchiveInputStream(new BufferedInputStream(
       156  
                           fis)), destination, filter);
       157  0
               } catch (ArchiveExtractionException ex) {
      @@ -281,12 +281,12 @@  160  
               } finally {
       161  0
                   try {
      -  162  3
                       fis.close();
      +  162  6
                       fis.close();
       163  0
                   } catch (IOException ex) {
       164  0
                       LOGGER.debug("", ex);
      -  165  3
                   }
      +  165  6
                   }
       166  0
               }
      -  167  3
           }
      +  167  6
           }
       168  
       
       169   @@ -315,8 +315,8 @@
               ArchiveEntry entry;
       181  
               try {
      -  182  36
                   while ((entry = input.getNextEntry()) != null) {
      -  183  33
                       if (entry.isDirectory()) {
      +  182  72
                   while ((entry = input.getNextEntry()) != null) {
      +  183  66
                       if (entry.isDirectory()) {
       184  0
                           final File dir = new File(destination, entry.getName());
       185  0
                           if (!dir.exists() && !dir.mkdirs()) {
       186  0
                               final String msg = String.format(
      @@ -327,7 +327,7 @@  190  
                           }
       191  0
                       } else {
      -  192  33
                           extractFile(input, destination, filter, entry);
      +  192  66
                           extractFile(input, destination, filter, entry);
       193  
                       }
       194   @@ -338,9 +338,9 @@  198  0
                   throw new ArchiveExtractionException(ex);
       199  
               } finally {
      -  200  3
                   closeStream(input);
      -  201  3
               }
      -  202  3
           }
      +  200  6
                   closeStream(input);
      +  201  6
               }
      +  202  6
           }
       203  
       
       204   @@ -365,16 +365,16 @@
           private static void extractFile(ArchiveInputStream input, File destination,
       214  
                   FilenameFilter filter, ArchiveEntry entry) throws ExtractionException {
      -  215  33
               final File file = new File(destination, entry.getName());
      -  216  33
               if (filter.accept(file.getParentFile(), file.getName())) {
      -  217  6
                   LOGGER.debug("Extracting '{}'",
      -  218  3
                           file.getPath());
      -  219  3
                   FileOutputStream fos = null;
      +  215  66
               final File file = new File(destination, entry.getName());
      +  216  66
               if (filter.accept(file.getParentFile(), file.getName())) {
      +  217  12
                   LOGGER.debug("Extracting '{}'",
      +  218  6
                           file.getPath());
      +  219  6
                   FileOutputStream fos = null;
       220  
                   try {
      -  221  3
                       createParentFile(file);
      -  222  3
                       fos = new FileOutputStream(file);
      -  223  3
                       IOUtils.copy(input, fos);
      +  221  6
                       createParentFile(file);
      +  222  6
                       fos = new FileOutputStream(file);
      +  223  6
                       IOUtils.copy(input, fos);
       224  0
                   } catch (FileNotFoundException ex) {
       225  0
                       LOGGER.debug("", ex);
       226  0
                       final String msg = String.format("Unable to find file '%s'.",
      @@ -388,11 +388,11 @@  234  0
                       throw new ExtractionException(msg, ex);
       235  
                   } finally {
      -  236  3
                       closeStream(fos);
      -  237  3
                   }
      +  236  6
                       closeStream(fos);
      +  237  6
                   }
       238  
               }
      -  239  33
           }
      +  239  66
           }
       240  
       
       241   @@ -407,16 +407,16 @@
            */
       246  
           private static void closeStream(Closeable stream) {
      -  247  6
               if (stream != null) {
      +  247  12
               if (stream != null) {
       248  
                   try {
      -  249  6
                       stream.close();
      +  249  12
                       stream.close();
       250  0
                   } catch (IOException ex) {
       251  0
                       LOGGER.trace("", ex);
      -  252  6
                   }
      +  252  12
                   }
       253  
               }
      -  254  6
           }
      +  254  12
           }
       255  
       
       256   @@ -435,8 +435,8 @@
           private static void createParentFile(final File file)
       263  
                   throws ExtractionException {
      -  264  3
               final File parent = file.getParentFile();
      -  265  3
               if (!parent.isDirectory() && !parent.mkdirs()) {
      +  264  6
               final File parent = file.getParentFile();
      +  265  6
               if (!parent.isDirectory() && !parent.mkdirs()) {
       266  0
                   final String msg = String.format(
       267  
                           "Unable to build directory '%s'.",
      @@ -444,11 +444,11 @@  269  0
                   throw new ExtractionException(msg);
       270  
               }
      -  271  3
           }
      +  271  6
           }
       272  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html index 81a91b952..94774f548 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html @@ -107,7 +107,7 @@
        * @see <a href="https://en.wikipedia.org/wiki/Builder_pattern">Builder pattern</a>
       45  
        */
      -  46  20
       public class FileFilterBuilder {
      +  46  40
       public class FileFilterBuilder {
       47  
       
       48   @@ -116,21 +116,21 @@
            * A set of filenames to filter.
       50  
            */
      -  51  20
           private final Set<String> filenames = new HashSet<String>();
      +  51  40
           private final Set<String> filenames = new HashSet<String>();
       52  
           /**
       53  
            * A set of extensions to filter.
       54  
            */
      -  55  20
           private final Set<String> extensions = new HashSet<String>();
      +  55  40
           private final Set<String> extensions = new HashSet<String>();
       56  
           /**
       57  
            * An array list of file filters.
       58  
            */
      -  59  20
           private final List<IOFileFilter> fileFilters = new ArrayList<IOFileFilter>();
      +  59  40
           private final List<IOFileFilter> fileFilters = new ArrayList<IOFileFilter>();
       60  
       
       61   @@ -145,7 +145,7 @@
            */
       66  
           public static FileFilterBuilder newInstance() {
      -  67  20
               return new FileFilterBuilder();
      +  67  40
               return new FileFilterBuilder();
       68  
           }
       69   @@ -164,8 +164,8 @@
            */
       76  
           public FileFilterBuilder addFilenames(String... names) {
      -  77  7
               filenames.addAll(Arrays.asList(names));
      -  78  7
               return this;
      +  77  12
               filenames.addAll(Arrays.asList(names));
      +  78  12
               return this;
       79  
           }
       80   @@ -184,7 +184,7 @@
            */
       87  
           public FileFilterBuilder addExtensions(String... extensions) {
      -  88  15
               return this.addExtensions(Arrays.asList(extensions));
      +  88  30
               return this.addExtensions(Arrays.asList(extensions));
       89  
           }
       90   @@ -203,12 +203,12 @@
            */
       97  
           public FileFilterBuilder addExtensions(Iterable<String> extensions) {
      -  98  16
               for (String extension : extensions) {
      +  98  32
               for (String extension : extensions) {
       99  
                   // Ultimately, SuffixFileFilter will be used, and the "." needs to be explicit.
      -  100  39
                   this.extensions.add(extension.startsWith(".") ? extension : "." + extension);
      -  101  39
               }
      -  102  16
               return this;
      +  100  78
                   this.extensions.add(extension.startsWith(".") ? extension : "." + extension);
      +  101  78
               }
      +  102  32
               return this;
       103  
           }
       104   @@ -227,8 +227,8 @@
            */
       111  
           public FileFilterBuilder addFileFilters(IOFileFilter... filters) {
      -  112  1
               fileFilters.addAll(Arrays.asList(filters));
      -  113  1
               return this;
      +  112  2
               fileFilters.addAll(Arrays.asList(filters));
      +  113  2
               return this;
       114  
           }
       115   @@ -247,29 +247,29 @@
            */
       122  
           public FileFilter build() {
      -  123  20
               if (filenames.isEmpty() && extensions.isEmpty() && fileFilters.isEmpty()) {
      +  123  40
               if (filenames.isEmpty() && extensions.isEmpty() && fileFilters.isEmpty()) {
       124  0
                   throw new IllegalStateException("May only be invoked after at least one add... method has been invoked.");
       125  
               }
      -  126  20
               final OrFileFilter filter = new OrFileFilter();
      -  127  20
               if (!filenames.isEmpty()) {
      -  128  7
                   filter.addFileFilter(new NameFileFilter(new ArrayList<String>(filenames)));
      +  126  40
               final OrFileFilter filter = new OrFileFilter();
      +  127  40
               if (!filenames.isEmpty()) {
      +  128  12
                   filter.addFileFilter(new NameFileFilter(new ArrayList<String>(filenames)));
       129  
               }
      -  130  20
               if (!extensions.isEmpty()) {
      -  131  16
                   filter.addFileFilter(new SuffixFileFilter(new ArrayList<String>(extensions), IOCase.INSENSITIVE));
      +  130  40
               if (!extensions.isEmpty()) {
      +  131  32
                   filter.addFileFilter(new SuffixFileFilter(new ArrayList<String>(extensions), IOCase.INSENSITIVE));
       132  
               }
      -  133  20
               for (IOFileFilter iof : fileFilters) {
      -  134  2
                   filter.addFileFilter(iof);
      -  135  2
               }
      -  136  20
               return filter;
      +  133  40
               for (IOFileFilter iof : fileFilters) {
      +  134  4
                   filter.addFileFilter(iof);
      +  135  4
               }
      +  136  40
               return filter;
       137  
           }
       138  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html index 8cd7abba6..0f42d2ae1 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html @@ -12,7 +12,7 @@
       
      - + @@ -47,7 +47,7 @@ - + @@ -56,21 +56,21 @@ - + - + - + @@ -79,7 +79,7 @@ - + @@ -88,17 +88,17 @@ - - - - + + + + - + @@ -107,13 +107,13 @@ - + - - - + + + @@ -129,22 +129,22 @@ - - - - - - + + + + + + - - + +
      Classes in this File Line Coverage Branch Coverage Complexity
      Filter
      100%
      4/4
      N/A
      1.667
      Filter
      100%
      3/3
      N/A
      1.667
      Filter$1
      100%
      2/2
      N/A
      1.667
      Filter$FilterIterator
      90%
      18/20
      80%
      8/10
      1.667
        * https://plus.google.com/115403795880834599019/?rel=author
       14  
        */
       15  6
       public abstract class Filter<T> {
       15  12
       public abstract class Filter<T> {
       16  
       
       17  
       
       19  
           public Iterator<T> filter(Iterator<T> iterator) {
       20  170
               return new FilterIterator(iterator);
       20  246
               return new FilterIterator(iterator);
       21  
           }
       22  
       
       23  
           public Iterable<T> filter(final Iterable<T> iterable) {
       24  170
               return new Iterable<T>() {
       24  246
               return new Iterable<T>() {
       25  
       
       26  
                   @Override
       27  
                   public Iterator<T> iterator() {
       28  170
                       return filter(iterable.iterator());
       28  246
                       return filter(iterable.iterator());
       29  
                   }
       30  
           }
       32  
       
       33  170
           private class FilterIterator implements Iterator<T> {
       33  246
           private class FilterIterator implements Iterator<T> {
       34  
       
       35  
               private T next;
       37  
       
       38  170
               private FilterIterator(Iterator<T> iterator) {
       39  170
                   this.iterator = iterator;
       40  170
                   toNext();
       41  170
               }
       38  246
               private FilterIterator(Iterator<T> iterator) {
       39  246
                   this.iterator = iterator;
       40  246
                   toNext();
       41  246
               }
       42  
       
       43  
               @Override
       44  
               public boolean hasNext() {
       45  528
                   return next != null;
       45  914
                   return next != null;
       46  
               }
       47  
               @Override
       49  
               public T next() {
       50  385
                   if (next == null) {
       50  716
                   if (next == null) {
       51  0
                       throw new NoSuchElementException();
       52  
                   }
       53  385
                   final T returnValue = next;
       54  385
                   toNext();
       55  385
                   return returnValue;
       53  716
                   final T returnValue = next;
       54  716
                   toNext();
       55  716
                   return returnValue;
       56  
               }
       57  
       
       63  
               private void toNext() {
       64  555
                   next = null;
       65  1477
                   while (iterator.hasNext()) {
       66  1329
                       final T item = iterator.next();
       67  1329
                       if (item != null && passes(item)) {
       68  407
                           next = item;
       69  407
                           break;
       64  962
                   next = null;
       65  1766
                   while (iterator.hasNext()) {
       66  1564
                       final T item = iterator.next();
       67  1564
                       if (item != null && passes(item)) {
       68  760
                           next = item;
       69  760
                           break;
       70  
                       }
       71  922
                   }
       72  555
               }
       71  804
                   }
       72  962
               }
       73  
           }
       74  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Pair.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Pair.html index c69209d8e..995685a2b 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Pair.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Pair.html @@ -97,17 +97,17 @@
            * @param right the value for the right pair
       41  
            */
      -  42  25715
           public Pair(L left, R right) {
      -  43  25715
               this.left = left;
      -  44  25715
               this.right = right;
      -  45  25715
           }
      +  42  103668
           public Pair(L left, R right) {
      +  43  103668
               this.left = left;
      +  44  103668
               this.right = right;
      +  45  103668
           }
       46  
           /**
       47  
            * The left element of the pair.
       48  
            */
      -  49  25715
           private L left = null;
      +  49  103668
           private L left = null;
       50  
       
       51   @@ -122,7 +122,7 @@
            */
       56  
           public L getLeft() {
      -  57  25715
               return left;
      +  57  103668
               return left;
       58  
           }
       59   @@ -147,7 +147,7 @@
            * The right element of the pair.
       70  
            */
      -  71  25715
           private R right = null;
      +  71  103668
           private R right = null;
       72  
       
       73   @@ -162,7 +162,7 @@
            */
       78  
           public R getRight() {
      -  79  25715
               return right;
      +  79  103668
               return right;
       80  
           }
       81   @@ -197,10 +197,10 @@
           @Override
       97  
           public int hashCode() {
      -  98  25715
               int hash = 3;
      -  99  25715
               hash = 53 * hash + (this.left != null ? this.left.hashCode() : 0);
      -  100  25715
               hash = 53 * hash + (this.right != null ? this.right.hashCode() : 0);
      -  101  25715
               return hash;
      +  98  103668
               int hash = 3;
      +  99  103668
               hash = 53 * hash + (this.left != null ? this.left.hashCode() : 0);
      +  100  103668
               hash = 53 * hash + (this.right != null ? this.right.hashCode() : 0);
      +  101  103668
               return hash;
       102  
           }
       103   @@ -245,6 +245,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.UrlStringUtils.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.UrlStringUtils.html index 406fd5870..6a1a58943 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.UrlStringUtils.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.UrlStringUtils.html @@ -99,14 +99,14 @@
            * A regular expression to test if a string contains a URL.
       42  
            */
      -  43  1
           private static final Pattern CONTAINS_URL_TEST = Pattern.compile("^.*(ht|f)tps?://.*$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
      +  43  2
           private static final Pattern CONTAINS_URL_TEST = Pattern.compile("^.*(ht|f)tps?://.*$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
       44  
           /**
       45  
            * A regular expression to test if a string is a URL.
       46  
            */
      -  47  1
           private static final Pattern IS_URL_TEST = Pattern.compile("^(ht|f)tps?://.*", Pattern.CASE_INSENSITIVE);
      +  47  2
           private static final Pattern IS_URL_TEST = Pattern.compile("^(ht|f)tps?://.*", Pattern.CASE_INSENSITIVE);
       48  
       
       49   @@ -125,7 +125,7 @@
            */
       56  
           public static boolean containsUrl(String text) {
      -  57  22176
               return CONTAINS_URL_TEST.matcher(text).matches();
      +  57  40463
               return CONTAINS_URL_TEST.matcher(text).matches();
       58  
           }
       59   @@ -144,7 +144,7 @@
            */
       66  
           public static boolean isUrl(String text) {
      -  67  33
               return IS_URL_TEST.matcher(text).matches();
      +  67  66
               return IS_URL_TEST.matcher(text).matches();
       68  
           }
       69   @@ -153,8 +153,8 @@
            * A listing of domain parts that should not be used as evidence. Yes, this is an incomplete list.
       71  
            */
      -  72  2
           private static final Set<String> IGNORE_LIST = new HashSet<String>(
      -  73  1
                   Arrays.asList("www", "com", "org", "gov", "info", "name", "net", "pro", "tel", "mobi", "xxx"));
      +  72  4
           private static final Set<String> IGNORE_LIST = new HashSet<String>(
      +  73  2
                   Arrays.asList("www", "com", "org", "gov", "info", "name", "net", "pro", "tel", "mobi", "xxx"));
       74  
       
       75   @@ -187,40 +187,40 @@
            */
       89  
           public static List<String> extractImportantUrlData(String text) throws MalformedURLException {
      -  90  25
               final List<String> importantParts = new ArrayList<String>();
      -  91  25
               final URL url = new URL(text);
      -  92  25
               final String[] domain = url.getHost().split("\\.");
      +  90  50
               final List<String> importantParts = new ArrayList<String>();
      +  91  50
               final URL url = new URL(text);
      +  92  50
               final String[] domain = url.getHost().split("\\.");
       93  
               //add the domain except www and the tld.
      -  94  72
               for (int i = 0; i < domain.length - 1; i++) {
      -  95  47
                   final String sub = domain[i];
      -  96  47
                   if (!IGNORE_LIST.contains(sub.toLowerCase())) {
      -  97  44
                       importantParts.add(sub);
      +  94  144
               for (int i = 0; i < domain.length - 1; i++) {
      +  95  94
                   final String sub = domain[i];
      +  96  94
                   if (!IGNORE_LIST.contains(sub.toLowerCase())) {
      +  97  88
                       importantParts.add(sub);
       98  
                   }
       99  
               }
      -  100  25
               final String document = url.getPath();
      -  101  25
               final String[] pathParts = document.split("[\\//]");
      -  102  44
               for (int i = 0; i < pathParts.length - 2; i++) {
      -  103  19
                   if (!pathParts[i].isEmpty()) {
      +  100  50
               final String document = url.getPath();
      +  101  50
               final String[] pathParts = document.split("[\\//]");
      +  102  88
               for (int i = 0; i < pathParts.length - 2; i++) {
      +  103  38
                   if (!pathParts[i].isEmpty()) {
       104  0
                       importantParts.add(pathParts[i]);
       105  
                   }
       106  
               }
      -  107  25
               if (pathParts.length > 0 && !pathParts[pathParts.length - 1].isEmpty()) {
      -  108  22
                   final String fileNameNoExt = pathParts[pathParts.length - 1].replaceAll("\\..*{0,5}$", "");
      -  109  22
                   importantParts.add(fileNameNoExt);
      +  107  50
               if (pathParts.length > 0 && !pathParts[pathParts.length - 1].isEmpty()) {
      +  108  44
                   final String fileNameNoExt = pathParts[pathParts.length - 1].replaceAll("\\..*{0,5}$", "");
      +  109  44
                   importantParts.add(fileNameNoExt);
       110  
               }
      -  111  25
               return importantParts;
      +  111  50
               return importantParts;
       112  
           }
       113  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.License.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.License.html index b45a8106d..272f90d1f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.License.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.License.html @@ -89,12 +89,12 @@
            * @param url the license url
       37  
            */
      -  38  3
           public License(String name, String url) {
      -  39  3
               this.url = url;
      -  40  3
               this.name = name;
      +  38  6
           public License(String name, String url) {
      +  39  6
               this.url = url;
      +  40  6
               this.name = name;
       41  
       
      -  42  3
           }
      +  42  6
           }
       43  
       
       44   @@ -221,24 +221,24 @@
           @Override
       110  
           public boolean equals(Object obj) {
      -  111  1
               if (obj == null) {
      +  111  2
               if (obj == null) {
       112  0
                   return false;
       113  
               }
      -  114  1
               if (getClass() != obj.getClass()) {
      +  114  2
               if (getClass() != obj.getClass()) {
       115  0
                   return false;
       116  
               }
      -  117  1
               final License other = (License) obj;
      -  118  1
               if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) {
      +  117  2
               final License other = (License) obj;
      +  118  2
               if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) {
       119  0
                   return false;
       120  
               }
      -  121  1
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
      +  121  2
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
       122  0
                   return false;
       123  
               }
      -  124  1
               return true;
      +  124  2
               return true;
       125  
           }
       126   @@ -266,6 +266,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.Model.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.Model.html index a73d0507b..2d4052f1c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.Model.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.Model.html @@ -12,8 +12,8 @@
       
      - - + +
      Classes in this File Line Coverage Branch Coverage Complexity
      Model
      94%
      48/51
      83%
      5/6
      1.167
      Model$PropertyLookup
      100%
      4/4
      N/A
      1.167
      Model
      94%
      51/54
      83%
      5/6
      1.154
      Model$PropertyLookup
      100%
      4/4
      N/A
      1.154
       
      @@ -80,7 +80,7 @@
        * @author jeremy
       31  
        */
      -  32  23
       public class Model {
      +  32  48
       public class Model {
       33  
       
       34   @@ -105,7 +105,7 @@
            */
       44  
           public String getName() {
      -  45  4
               return name;
      +  45  10
               return name;
       46  
           }
       47   @@ -122,8 +122,8 @@
            */
       53  
           public void setName(String name) {
      -  54  5
               this.name = name;
      -  55  5
           }
      +  54  12
               this.name = name;
      +  55  12
           }
       56  
       
       57   @@ -148,7 +148,7 @@
            */
       67  
           public String getOrganization() {
      -  68  2
               return organization;
      +  68  6
               return organization;
       69  
           }
       70   @@ -165,8 +165,8 @@
            */
       76  
           public void setOrganization(String organization) {
      -  77  2
               this.organization = organization;
      -  78  2
           }
      +  77  4
               this.organization = organization;
      +  78  4
           }
       79  
       
       80   @@ -191,7 +191,7 @@
            */
       90  
           public String getDescription() {
      -  91  2
               return description;
      +  91  6
               return description;
       92  
           }
       93   @@ -208,8 +208,8 @@
            */
       99  
           public void setDescription(String description) {
      -  100  3
               this.description = description;
      -  101  3
           }
      +  100  8
               this.description = description;
      +  101  8
           }
       102  
       
       103   @@ -234,7 +234,7 @@
            */
       113  
           public String getGroupId() {
      -  114  2
               return groupId;
      +  114  6
               return groupId;
       115  
           }
       116   @@ -251,8 +251,8 @@
            */
       122  
           public void setGroupId(String groupId) {
      -  123  4
               this.groupId = groupId;
      -  124  4
           }
      +  123  10
               this.groupId = groupId;
      +  124  10
           }
       125  
       
       126   @@ -277,7 +277,7 @@
            */
       136  
           public String getArtifactId() {
      -  137  2
               return artifactId;
      +  137  6
               return artifactId;
       138  
           }
       139   @@ -294,8 +294,8 @@
            */
       145  
           public void setArtifactId(String artifactId) {
      -  146  4
               this.artifactId = artifactId;
      -  147  4
           }
      +  146  10
               this.artifactId = artifactId;
      +  147  10
           }
       148  
       
       149   @@ -320,7 +320,7 @@
            */
       159  
           public String getVersion() {
      -  160  2
               return version;
      +  160  6
               return version;
       161  
           }
       162   @@ -337,8 +337,8 @@
            */
       168  
           public void setVersion(String version) {
      -  169  3
               this.version = version;
      -  170  3
           }
      +  169  8
               this.version = version;
      +  170  8
           }
       171  
       
       172   @@ -363,7 +363,7 @@
            */
       182  
           public String getParentGroupId() {
      -  183  2
               return parentGroupId;
      +  183  6
               return parentGroupId;
       184  
           }
       185   @@ -380,8 +380,8 @@
            */
       191  
           public void setParentGroupId(String parentGroupId) {
      -  192  3
               this.parentGroupId = parentGroupId;
      -  193  3
           }
      +  192  6
               this.parentGroupId = parentGroupId;
      +  193  6
           }
       194  
       
       195   @@ -406,7 +406,7 @@
            */
       205  
           public String getParentArtifactId() {
      -  206  2
               return parentArtifactId;
      +  206  6
               return parentArtifactId;
       207  
           }
       208   @@ -423,8 +423,8 @@
            */
       214  
           public void setParentArtifactId(String parentArtifactId) {
      -  215  3
               this.parentArtifactId = parentArtifactId;
      -  216  3
           }
      +  215  6
               this.parentArtifactId = parentArtifactId;
      +  216  6
           }
       217  
       
       218   @@ -449,7 +449,7 @@
            */
       228  
           public String getParentVersion() {
      -  229  2
               return parentVersion;
      +  229  6
               return parentVersion;
       230  
           }
       231   @@ -466,8 +466,8 @@
            */
       237  
           public void setParentVersion(String parentVersion) {
      -  238  3
               this.parentVersion = parentVersion;
      -  239  3
           }
      +  238  6
               this.parentVersion = parentVersion;
      +  239  6
           }
       240  
       
       241   @@ -476,7 +476,7 @@
            * The list of licenses.
       243  
            */
      -  244  23
           private final List<License> licenses = new ArrayList<License>();
      +  244  48
           private final List<License> licenses = new ArrayList<License>();
       245  
       
       246   @@ -491,7 +491,7 @@
            */
       251  
           public List<License> getLicenses() {
      -  252  5
               return licenses;
      +  252  16
               return licenses;
       253  
           }
       254   @@ -508,163 +508,216 @@
            */
       260  
           public void addLicense(License license) {
      -  261  2
               licenses.add(license);
      -  262  2
           }
      +  261  4
               licenses.add(license);
      +  262  4
           }
       263  
       
       264  
           /**
       265   -
            * Process the Maven properties file and interpolate all properties.
      +
            * The project URL.
       266   -
            *
      +
            */
       267   -
            * @param properties new value of properties
      +
           private String projectURL;
       268   -
            */
      +
       
       269   -
           public void processProperties(Properties properties) {
      -  270  2
               this.groupId = interpolateString(this.groupId, properties);
      -  271  2
               this.artifactId = interpolateString(this.artifactId, properties);
      -  272  2
               this.version = interpolateString(this.version, properties);
      -  273  2
               this.description = interpolateString(this.description, properties);
      -  274  2
               for (License l : this.getLicenses()) {
      -  275  0
                   l.setName(interpolateString(l.getName(), properties));
      -  276  0
                   l.setUrl(interpolateString(l.getUrl(), properties));
      -  277  0
               }
      -  278  2
               this.name = interpolateString(this.name, properties);
      -  279  2
               this.organization = interpolateString(this.organization, properties);
      -  280  2
               this.parentGroupId = interpolateString(this.parentGroupId, properties);
      -  281  2
               this.parentArtifactId = interpolateString(this.parentArtifactId, properties);
      -  282  2
               this.parentVersion = interpolateString(this.parentVersion, properties);
      -  283   -
       
      -  284  2
           }
      -  285   -
       
      -  286  
           /**
      -  287   -
            * <p>
      -  288   -
            * A utility function that will interpolate strings based on values given in the properties file. It will also interpolate the
      -  289   -
            * strings contained within the properties file so that properties can reference other properties.</p>
      -  290   -
            * <p>
      -  291   -
            * <b>Note:</b> if there is no property found the reference will be removed. In other words, if the interpolated string will
      -  292   -
            * be replaced with an empty string.
      -  293   -
            * </p>
      -  294   -
            * <p>
      -  295   -
            * Example:</p>
      -  296   -
            * <code>
      -  297   -
            * Properties p = new Properties();
      -  298   -
            * p.setProperty("key", "value");
      -  299   -
            * String s = interpolateString("'${key}' and '${nothing}'", p);
      -  300   -
            * System.out.println(s);
      -  301   -
            * </code>
      -  302   -
            * <p>
      -  303   -
            * Will result in:</p>
      -  304   -
            * <code>
      -  305   -
            * 'value' and ''
      -  306   -
            * </code>
      -  307   +  270   +
            * Get the value of projectURL.
      +  271  
            *
      -  308   -
            * @param text the string that contains references to properties.
      -  309   -
            * @param properties a collection of properties that may be referenced within the text.
      -  310   -
            * @return the interpolated text.
      -  311   +  272   +
            * @return the value of projectURL
      +  273  
            */
      -  312   -
           public static String interpolateString(String text, Properties properties) {
      -  313  19
               if (null == text || null == properties) {
      -  314  17
                   return text;
      -  315   -
               }
      -  316  2
               final StrSubstitutor substitutor = new StrSubstitutor(new PropertyLookup(properties));
      -  317  2
               return substitutor.replace(text);
      -  318   +  274   +
           public String getProjectURL() {
      +  275  4
               return projectURL;
      +  276  
           }
      -  319   +  277  
       
      -  320   +  278  
           /**
      -  321   -
            * Utility class that can provide values from a Properties object to a StrSubstitutor.
      -  322   +  279   +
            * Set the value of projectURL.
      +  280   +
            *
      +  281   +
            * @param projectURL new value of projectURL
      +  282  
            */
      -  323  23
           private static class PropertyLookup extends StrLookup {
      +  283   +
           public void setProjectURL(String projectURL) {
      +  284  4
               this.projectURL = projectURL;
      +  285  4
           }
      +  286   +
       
      +  287   +
           /**
      +  288   +
            * Process the Maven properties file and interpolate all properties.
      +  289   +
            *
      +  290   +
            * @param properties new value of properties
      +  291   +
            */
      +  292   +
           public void processProperties(Properties properties) {
      +  293  6
               this.groupId = interpolateString(this.groupId, properties);
      +  294  6
               this.artifactId = interpolateString(this.artifactId, properties);
      +  295  6
               this.version = interpolateString(this.version, properties);
      +  296  6
               this.description = interpolateString(this.description, properties);
      +  297  6
               for (License l : this.getLicenses()) {
      +  298  0
                   l.setName(interpolateString(l.getName(), properties));
      +  299  0
                   l.setUrl(interpolateString(l.getUrl(), properties));
      +  300  0
               }
      +  301  6
               this.name = interpolateString(this.name, properties);
      +  302  6
               this.projectURL = interpolateString(this.projectURL, properties);
      +  303  6
               this.organization = interpolateString(this.organization, properties);
      +  304  6
               this.parentGroupId = interpolateString(this.parentGroupId, properties);
      +  305  6
               this.parentArtifactId = interpolateString(this.parentArtifactId, properties);
      +  306  6
               this.parentVersion = interpolateString(this.parentVersion, properties);
      +  307  6
           }
      +  308   +
       
      +  309   +
           /**
      +  310   +
            * <p>
      +  311   +
            * A utility function that will interpolate strings based on values given in
      +  312   +
            * the properties file. It will also interpolate the strings contained
      +  313   +
            * within the properties file so that properties can reference other
      +  314   +
            * properties.</p>
      +  315   +
            * <p>
      +  316   +
            * <b>Note:</b> if there is no property found the reference will be removed.
      +  317   +
            * In other words, if the interpolated string will be replaced with an empty
      +  318   +
            * string.
      +  319   +
            * </p>
      +  320   +
            * <p>
      +  321   +
            * Example:</p>
      +  322   +
            * <code>
      +  323   +
            * Properties p = new Properties();
       324   -
       
      +
            * p.setProperty("key", "value");
       325   -
               /**
      +
            * String s = interpolateString("'${key}' and '${nothing}'", p);
       326   -
                * Reference to the properties to lookup.
      +
            * System.out.println(s);
       327   -
                */
      +
            * </code>
       328   -
               private final Properties props;
      +
            * <p>
       329   -
       
      +
            * Will result in:</p>
       330   -
               /**
      +
            * <code>
       331   -
                * Constructs a new property lookup.
      +
            * 'value' and ''
       332   -
                *
      +
            * </code>
       333   -
                * @param props the properties to wrap.
      +
            *
       334   -
                */
      -  335  2
               PropertyLookup(Properties props) {
      -  336  2
                   this.props = props;
      -  337  2
               }
      +
            * @param text the string that contains references to properties.
      +  335   +
            * @param properties a collection of properties that may be referenced
      +  336   +
            * within the text.
      +  337   +
            * @return the interpolated text.
       338   -
       
      +
            */
       339   -
               /**
      -  340   -
                * Looks up the given property.
      -  341   -
                *
      +
           public static String interpolateString(String text, Properties properties) {
      +  340  62
               if (null == text || null == properties) {
      +  341  58
                   return text;
       342   -
                * @param key the key to the property
      -  343   -
                * @return the value of the property specified by the key
      -  344   -
                */
      -  345   -
               @Override
      -  346   -
               public String lookup(String key) {
      -  347  6
                   return props.getProperty(key);
      -  348  
               }
      -  349   +  343  4
               final StrSubstitutor substitutor = new StrSubstitutor(new PropertyLookup(properties));
      +  344  4
               return substitutor.replace(text);
      +  345  
           }
      +  346   +
       
      +  347   +
           /**
      +  348   +
            * Utility class that can provide values from a Properties object to a
      +  349   +
            * StrSubstitutor.
       350   +
            */
      +  351   +
           private static class PropertyLookup extends StrLookup {
      +  352   +
       
      +  353   +
               /**
      +  354   +
                * Reference to the properties to lookup.
      +  355   +
                */
      +  356   +
               private final Properties props;
      +  357   +
       
      +  358   +
               /**
      +  359   +
                * Constructs a new property lookup.
      +  360   +
                *
      +  361   +
                * @param props the properties to wrap.
      +  362   +
                */
      +  363  4
               PropertyLookup(Properties props) {
      +  364  4
                   this.props = props;
      +  365  4
               }
      +  366   +
       
      +  367   +
               /**
      +  368   +
                * Looks up the given property.
      +  369   +
                *
      +  370   +
                * @param key the key to the property
      +  371   +
                * @return the value of the property specified by the key
      +  372   +
                */
      +  373   +
               @Override
      +  374   +
               public String lookup(String key) {
      +  375  12
                   return props.getProperty(key);
      +  376   +
               }
      +  377   +
           }
      +  378  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomHandler.html index 666d32ba0..44f464d97 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomHandler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomHandler.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      PomHandler
      77%
      35/45
      60%
      23/38
      5.75
      PomHandler
      78%
      37/47
      62%
      25/40
      6
       
      @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  2
       public class PomHandler extends DefaultHandler {
      +  31  6
       public class PomHandler extends DefaultHandler {
       32  
       
       33   @@ -176,7 +176,7 @@
            * The pom model.
       80  
            */
      -  81  2
           private final Model model = new Model();
      +  81  6
           private final Model model = new Model();
       82  
       
       83   @@ -191,7 +191,7 @@
            */
       88  
           public Model getModel() {
      -  89  2
               return model;
      +  89  6
               return model;
       90  
           }
       91   @@ -200,14 +200,14 @@
            * The stack of elements processed; used to determine the parent node.
       93  
            */
      -  94  2
           private final Deque<String> stack = new ArrayDeque<String>();
      +  94  6
           private final Deque<String> stack = new ArrayDeque<String>();
       95  
           /**
       96  
            * The license object.
       97  
            */
      -  98  2
           private License license = null;
      +  98  6
           private License license = null;
       99  
       
       100   @@ -242,13 +242,13 @@
           @Override
       115  
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      -  116  471
               currentText = new StringBuilder();
      -  117  471
               stack.push(qName);
      -  118  471
               if (LICENSE.equals(qName)) {
      +  116  1378
               currentText = new StringBuilder();
      +  117  1378
               stack.push(qName);
      +  118  1378
               if (LICENSE.equals(qName)) {
       119  0
                   license = new License();
       120  
               }
      -  121  471
           }
      +  121  1378
           }
       122  
       
       123   @@ -271,89 +271,91 @@
           @Override
       132  
           public void endElement(String uri, String localName, String qName) throws SAXException {
      -  133  471
               stack.pop();
      -  134  471
               final String parentNode = stack.peek();
      -  135  471
               if (PROJECT.equals(parentNode)) {
      -  136  29
                   if (GROUPID.equals(qName)) {
      -  137  2
                       model.setGroupId(currentText.toString());
      -  138  27
                   } else if (ARTIFACTID.equals(qName)) {
      -  139  2
                       model.setArtifactId(currentText.toString());
      -  140  25
                   } else if (VERSION.equals(qName)) {
      -  141  1
                       model.setVersion(currentText.toString());
      -  142  24
                   } else if (NAME.equals(qName)) {
      -  143  2
                       model.setName(currentText.toString());
      -  144  22
                   } else if (ORGANIZATION.equals(qName)) {
      +  133  1378
               stack.pop();
      +  134  1378
               final String parentNode = stack.peek();
      +  135  1378
               if (PROJECT.equals(parentNode)) {
      +  136  94
                   if (GROUPID.equals(qName)) {
      +  137  6
                       model.setGroupId(currentText.toString());
      +  138  88
                   } else if (ARTIFACTID.equals(qName)) {
      +  139  6
                       model.setArtifactId(currentText.toString());
      +  140  82
                   } else if (VERSION.equals(qName)) {
      +  141  4
                       model.setVersion(currentText.toString());
      +  142  78
                   } else if (NAME.equals(qName)) {
      +  143  6
                       model.setName(currentText.toString());
      +  144  72
                   } else if (ORGANIZATION.equals(qName)) {
       145  0
                       model.setOrganization(currentText.toString());
      -  146  22
                   } else if (DESCRIPTION.equals(qName)) {
      -  147  1
                       model.setDescription(currentText.toString());
      -  148   +  146  72
                   } else if (DESCRIPTION.equals(qName)) {
      +  147  4
                       model.setDescription(currentText.toString());
      +  148  68
                   } else if (URL.equals(qName)) {
      +  149  4
                       model.setProjectURL(currentText.toString());
      +  150  
                   }
      -  149  442
               } else if (PARENT.equals(parentNode)) {
      -  150  3
                   if (GROUPID.equals(qName)) {
      -  151  1
                       model.setParentGroupId(currentText.toString());
      -  152  2
                   } else if (ARTIFACTID.equals(qName)) {
      -  153  1
                       model.setParentArtifactId(currentText.toString());
      -  154  1
                   } else if (VERSION.equals(qName)) {
      -  155  1
                       model.setParentVersion(currentText.toString());
      -  156   +  151  1284
               } else if (PARENT.equals(parentNode)) {
      +  152  6
                   if (GROUPID.equals(qName)) {
      +  153  2
                       model.setParentGroupId(currentText.toString());
      +  154  4
                   } else if (ARTIFACTID.equals(qName)) {
      +  155  2
                       model.setParentArtifactId(currentText.toString());
      +  156  2
                   } else if (VERSION.equals(qName)) {
      +  157  2
                       model.setParentVersion(currentText.toString());
      +  158  
                   }
      -  157  439
               } else if (LICENSE.equals(parentNode)) {
      -  158  0
                   if (license != null) {
      -  159  0
                       if (NAME.equals(qName)) {
      -  160  0
                           license.setName(currentText.toString());
      -  161  0
                       } else if (URL.equals(qName)) {
      -  162  0
                           license.setUrl(currentText.toString());
      -  163   -
                       }
      -  164   -
                       //} else {
      +  159  1278
               } else if (LICENSE.equals(parentNode)) {
      +  160  0
                   if (license != null) {
      +  161  0
                       if (NAME.equals(qName)) {
      +  162  0
                           license.setName(currentText.toString());
      +  163  0
                       } else if (URL.equals(qName)) {
      +  164  0
                           license.setUrl(currentText.toString());
       165   -
                       //TODO add error logging
      -  166   -
                   }
      -  167  439
               } else if (LICENSES.equals(parentNode)) {
      -  168  0
                   if (LICENSE.equals(qName)) {
      -  169  0
                       if (license != null) {
      -  170  0
                           model.addLicense(license);
      -  171   -
                           //} else {
      -  172   -
                           //TODO add error logging
      -  173  
                       }
      -  174   +  166   +
                       //} else {
      +  167   +
                       //TODO add error logging
      +  168  
                   }
      +  169  1278
               } else if (LICENSES.equals(parentNode)) {
      +  170  0
                   if (LICENSE.equals(qName)) {
      +  171  0
                       if (license != null) {
      +  172  0
                           model.addLicense(license);
      +  173   +
                           //} else {
      +  174   +
                           //TODO add error logging
       175   -
               }
      -  176  471
           }
      +
                       }
      +  176   +
                   }
       177   -
       
      -  178   -
           /**
      +
               }
      +  178  1378
           }
       179   -
            * Collects the body text of the node being processed.
      +
       
       180   -
            *
      +
           /**
       181   -
            * @param ch the char array of text
      +
            * Collects the body text of the node being processed.
       182   -
            * @param start the start position to copy text from in the char array
      +
            *
       183   -
            * @param length the number of characters to copy from the char array
      +
            * @param ch the char array of text
       184   -
            * @throws SAXException thrown if there is a parsing exception
      +
            * @param start the start position to copy text from in the char array
       185   -
            */
      +
            * @param length the number of characters to copy from the char array
       186   -
           @Override
      +
            * @throws SAXException thrown if there is a parsing exception
       187   +
            */
      +  188   +
           @Override
      +  189  
           public void characters(char[] ch, int start, int length) throws SAXException {
      -  188  953
               currentText.append(ch, start, length);
      -  189  953
           }
      -  190   +  190  2760
               currentText.append(ch, start, length);
      +  191  2760
           }
      +  192  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParseException.html index ed3f4e175..c7dcda264 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParseException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParser.html index 84541ae13..b1199fdf0 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParser.html @@ -99,7 +99,7 @@
        * @author Jeremy Long
       41  
        */
      -  42  2
       public class PomParser {
      +  42  6
       public class PomParser {
       43  
       
       44   @@ -108,7 +108,7 @@
            * The logger.
       46  
            */
      -  47  1
           private static final Logger LOGGER = LoggerFactory.getLogger(PomParser.class);
      +  47  2
           private static final Logger LOGGER = LoggerFactory.getLogger(PomParser.class);
       48  
       
       49   @@ -127,20 +127,20 @@
            */
       56  
           public Model parse(File file) throws PomParseException {
      -  57  1
               FileInputStream fis = null;
      +  57  2
               FileInputStream fis = null;
       58  
               try {
      -  59  1
                   fis = new FileInputStream(file);
      -  60  1
                   return parse(fis);
      +  59  2
                   fis = new FileInputStream(file);
      +  60  4
                   return parse(fis);
       61  0
               } catch (IOException ex) {
       62  0
                   LOGGER.debug("", ex);
       63  0
                   throw new PomParseException(ex);
       64  
               } finally {
      -  65  1
                   if (fis != null) {
      +  65  2
                   if (fis != null) {
       66  
                       try {
      -  67  1
                           fis.close();
      +  67  2
                           fis.close();
       68  0
                       } catch (IOException ex) {
       69  0
                           LOGGER.debug("Unable to close stream", ex);
       70  2
                       }
      @@ -170,27 +170,27 @@
           public Model parse(InputStream inputStream) throws PomParseException {
       83  
               try {
      -  84  2
                   final PomHandler handler = new PomHandler();
      -  85  2
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
      +  84  6
                   final PomHandler handler = new PomHandler();
      +  85  6
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
       86  
       //            factory.setNamespaceAware(true);
       87  
       //            factory.setValidating(true);
      -  88  2
                   final SAXParser saxParser = factory.newSAXParser();
      -  89  2
                   final XMLReader xmlReader = saxParser.getXMLReader();
      -  90  2
                   xmlReader.setContentHandler(handler);
      +  88  6
                   final SAXParser saxParser = factory.newSAXParser();
      +  89  6
                   final XMLReader xmlReader = saxParser.getXMLReader();
      +  90  6
                   xmlReader.setContentHandler(handler);
       91  
       
      -  92  2
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
      -  93  2
                   final InputSource in = new InputSource(reader);
      +  92  6
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
      +  93  6
                   final InputSource in = new InputSource(reader);
       94  
                   //in.setEncoding("UTF-8");
       95  
       
      -  96  2
                   xmlReader.parse(in);
      +  96  6
                   xmlReader.parse(in);
       97  
       
      -  98  2
                   return handler.getModel();
      +  98  6
                   return handler.getModel();
       99  0
               } catch (ParserConfigurationException ex) {
       100  0
                   LOGGER.debug("", ex);
       101  0
                   throw new PomParseException(ex);
      @@ -211,6 +211,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomUtils.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomUtils.html index 80e20ceeb..124c47014 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomUtils.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomUtils.html @@ -101,7 +101,7 @@
            * The logger.
       43  
            */
      -  44  1
           private static final Logger LOGGER = LoggerFactory.getLogger(PomUtils.class);
      +  44  2
           private static final Logger LOGGER = LoggerFactory.getLogger(PomUtils.class);
       45  
       
       46   @@ -120,11 +120,11 @@
            */
       53  
           public static Model readPom(File file) throws AnalysisException {
      -  54  1
               Model model = null;
      +  54  2
               Model model = null;
       55  
               try {
      -  56  1
                   final PomParser parser = new PomParser();
      -  57  1
                   model = parser.parse(file);
      +  56  2
                   final PomParser parser = new PomParser();
      +  57  2
                   model = parser.parse(file);
       58  0
               } catch (PomParseException ex) {
       59  0
                   LOGGER.warn("Unable to parse pom '{}'", file.getPath());
       60  0
                   LOGGER.debug("", ex);
      @@ -137,8 +137,8 @@  67  0
                   LOGGER.warn("Unexpected error during parsing of the pom '{}'", file.getPath());
       68  0
                   LOGGER.debug("", ex);
       69  0
                   throw new AnalysisException(ex);
      -  70  1
               }
      -  71  1
               return model;
      +  70  2
               }
      +  71  2
               return model;
       72  
           }
       73   @@ -161,14 +161,14 @@
            */
       82  
           public static Model readPom(String path, JarFile jar) throws AnalysisException {
      -  83  1
               final ZipEntry entry = jar.getEntry(path);
      -  84  1
               Model model = null;
      -  85  1
               if (entry != null) { //should never be null
      +  83  4
               final ZipEntry entry = jar.getEntry(path);
      +  84  4
               Model model = null;
      +  85  4
               if (entry != null) { //should never be null
       86  
                   try {
      -  87  1
                       final PomParser parser = new PomParser();
      -  88  1
                       model = parser.parse(jar.getInputStream(entry));
      -  89  1
                       LOGGER.debug("Read POM {}", path);
      +  87  4
                       final PomParser parser = new PomParser();
      +  88  4
                       model = parser.parse(jar.getInputStream(entry));
      +  89  4
                       LOGGER.debug("Read POM {}", path);
       90  0
                   } catch (SecurityException ex) {
       91  0
                       LOGGER.warn("Unable to parse pom '{}' in jar '{}'; invalid signature", path, jar.getName());
       92  0
                       LOGGER.debug("", ex);
      @@ -181,10 +181,10 @@  99  0
                       LOGGER.warn("Unexpected error during parsing of the pom '{}' in jar '{}'", path, jar.getName());
       100  0
                       LOGGER.debug("", ex);
       101  0
                       throw new AnalysisException(ex);
      -  102  1
                   }
      +  102  4
                   }
       103  
               }
      -  104  1
               return model;
      +  104  4
               return model;
       105  
           }
       106   @@ -212,6 +212,6 @@
       }
      - + diff --git a/dependency-check-core/cpd.html b/dependency-check-core/cpd.html index cd3b57ab1..9b2b7724c 100644 --- a/dependency-check-core/cpd.html +++ b/dependency-check-core/cpd.html @@ -1,13 +1,13 @@ - + dependency-check-core – CPD Results @@ -52,7 +52,7 @@ @@ -228,9 +228,6 @@ developed using - - - built on cloudbees @@ -253,7 +250,7 @@ 147 org\owasp\dependencycheck\data\update\nvd\DownloadTask.java -267 +268
          }
      @@ -315,11 +312,46 @@
       File
       Line
       
      +org\owasp\dependencycheck\suppression\SuppressionParser.java
      +117
      +
      +org\owasp\dependencycheck\suppression\SuppressionParser.java
      +165
      +
      +
      +
                  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) {
      + + + + + - + - +
      FileLine
      org\owasp\dependencycheck\analyzer\JarAnalyzer.java895
      910
      org\owasp\dependencycheck\analyzer\PythonDistributionAnalyzer.java235
      236
          public void initializeFileTypeAnalyzer() throws Exception {
      @@ -350,11 +382,13 @@
           }
       
           /**
      -     * Determines if the key value pair from the manifest is for an "import" type entry for package names.
      +     * Determines if the key value pair from the manifest is for an "import"
      +     * type entry for package names.
            *
            * @param key the key from the manifest
            * @param value the value from the manifest
      -     * @return true or false depending on if it is believed the entry is an "import" entry
      +     * @return true or false depending on if it is believed the entry is an
      +     * "import" entry
            */
           private boolean isImportPackage(String key, String value) {
      @@ -366,7 +400,7 @@ - + - + - + @@ -303,7 +300,7 @@ - + @@ -359,7 +356,7 @@ - + diff --git a/dependency-check-core/dependency-updates-report.html b/dependency-check-core/dependency-updates-report.html index bd8865bf7..7550d79ec 100644 --- a/dependency-check-core/dependency-updates-report.html +++ b/dependency-check-core/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-core – Dependency Updates Report @@ -52,7 +52,7 @@ @@ -228,9 +228,6 @@ developed using - - - built on cloudbees @@ -246,7 +243,7 @@ - + @@ -254,11 +251,11 @@ - + - + @@ -366,7 +363,7 @@ - + @@ -390,7 +387,7 @@ - + @@ -402,7 +399,7 @@ - + @@ -483,39 +480,39 @@ - + - + - + - + - + - + - + - + - + @@ -591,7 +588,7 @@ - + @@ -600,18 +597,18 @@ - + - + - + - + @@ -794,8 +791,8 @@ - - + + @@ -825,7 +822,7 @@ - + @@ -1033,7 +1030,7 @@ -
      174
      org\owasp\dependencycheck\analyzer\JarAnalyzer.java894
      909
          @Override
      @@ -399,7 +433,7 @@
       
      175
      org\owasp\dependencycheck\analyzer\PythonDistributionAnalyzer.java235
      236
          public void initializeFileTypeAnalyzer() throws Exception {
      diff --git a/dependency-check-core/dependency-analysis.html b/dependency-check-core/dependency-analysis.html
      index 30b74e585..e340a25d0 100644
      --- a/dependency-check-core/dependency-analysis.html
      +++ b/dependency-check-core/dependency-analysis.html
      @@ -1,13 +1,13 @@
       
       
       
         
           
           
      -    
      +    
           
           dependency-check-core – Dependencies Report
           
      @@ -52,7 +52,7 @@
               
      @@ -228,9 +228,6 @@
             
                                                                                                           
               developed using
      -      
      -                                                                                                    
      -        built on cloudbees
             
                             
      @@ -271,7 +268,7 @@
      org.owasp dependency-check-utils1.3.61.4.0 compile jar
      commons-io commons-io2.42.5 compile jar
      org.jsoup jsoup1.8.31.9.1 compile jar
      # of dependencies using the latest version available24
      25
      # of dependencies where the next version available is smaller than an incremental version update
      # of dependencies where the next version available is an incremental version update10
      7
      # of dependencies where the next version available is a minor version update13
      15
      # of dependencies where the next version available is a major version update commons-io commons-io2.42.5 jar org.apache.ant ant1.9.61.9.7 jar org.apache.ant ant-testutil1.9.61.9.7 jar4.8.0 5.0.0
      org.apache.maven maven-core3.3.33.3.9 jar 3.3.9
      org.apache.maven maven-plugin-api3.3.33.3.9 jar 3.3.9
      org.apache.maven maven-settings3.3.33.3.9 jar 3.3.9
      org.jmockit jmockit 1.22jar 1.23
      org.jsoup jsoup1.8.31.9.1 jar 1.9.2
      war 1.3.11.4.21.11.1
      org.owasp dependency-check-utils1.3.61.4.0 compile jarjar
      Newer versions1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191 Latest Minor
      +1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191
      1.4.192 Latest Minor

      com.hazelcast:hazelcast

      @@ -1060,7 +1057,7 @@ -
      jar
      Newer versions2.5.1 Next Incremental
      2.6 Next Minor
      2.6.1
      2.6.2
      2.6.3
      2.6.4
      2.6.5
      2.6.6
      2.6.7
      2.6.8
      2.6.9
      3.0-RC1
      3.0-RC2 Latest Minor
      3.0 Next Major
      3.0.1
      3.0.2
      3.0.3
      3.1
      3.1.1
      3.1.2
      3.1.3
      3.1.4
      3.1.5
      3.1.6
      3.1.7
      3.1.8
      3.2-RC1
      3.2-RC2
      3.2
      3.2.1
      3.2.2
      3.2.3
      3.2.4
      3.2.5
      3.2.6
      3.3-RC1
      3.3-RC2
      3.3-RC3
      3.3
      3.3-EA
      3.3-EA2
      3.3.1
      3.3.2
      3.3.3
      3.3.4
      3.3.5
      3.4
      3.4-EA
      3.4.1
      3.4.2
      3.4.5
      3.4.6
      3.4.7
      3.5-EA
      3.5.1
      3.5.2
      3.5.3
      3.5.4
      3.5.5
      3.6-RC1
      3.6
      3.6-EA
      3.6-EA2
      3.6-EA3
      3.6.1
      3.6.2 Latest Major
      +2.5.1 Next Incremental
      2.6 Next Minor
      2.6.1
      2.6.2
      2.6.3
      2.6.4
      2.6.5
      2.6.6
      2.6.7
      2.6.8
      2.6.9
      3.0-RC1
      3.0-RC2 Latest Minor
      3.0 Next Major
      3.0.1
      3.0.2
      3.0.3
      3.1
      3.1.1
      3.1.2
      3.1.3
      3.1.4
      3.1.5
      3.1.6
      3.1.7
      3.1.8
      3.2-RC1
      3.2-RC2
      3.2
      3.2.1
      3.2.2
      3.2.3
      3.2.4
      3.2.5
      3.2.6
      3.3-RC1
      3.3-RC2
      3.3-RC3
      3.3
      3.3-EA
      3.3-EA2
      3.3.1
      3.3.2
      3.3.3
      3.3.4
      3.3.5
      3.4
      3.4-EA
      3.4.1
      3.4.2
      3.4.5
      3.4.6
      3.4.7
      3.4.8
      3.5-EA
      3.5.1
      3.5.2
      3.5.3
      3.5.4
      3.5.5
      3.6-RC1
      3.6
      3.6-EA
      3.6-EA2
      3.6-EA3
      3.6.1
      3.6.2
      3.6.3
      3.7-EA Latest Major

      com.sun.mail:mailapi

      @@ -1150,7 +1147,7 @@ - + @@ -1225,7 +1222,7 @@ - + @@ -1249,7 +1246,7 @@ - + @@ -1285,7 +1282,7 @@ -
      commons-io
      Current Version2.4
      2.5
      Scope
      ant
      Current Version1.9.6
      1.9.7
      Scope
      ant-testutil
      Current Version1.9.6
      1.9.7
      Scope
      jar
      Newer versions1.5 Next Minor
      1.5.1
      1.5.2
      1.5.3
      1.5.4
      1.5.5
      1.5.6
      1.6.0
      1.6.1
      1.6.2
      1.6.3
      1.6.4
      1.7.0
      1.7.1 Latest Minor
      +1.5 Next Minor
      1.5.1
      1.5.2
      1.5.3
      1.5.4
      1.5.5
      1.5.6
      1.6.0
      1.6.1
      1.6.2
      1.6.3
      1.6.4
      1.7.0
      1.7.1
      1.7.2
      1.7.3 Latest Minor

      org.apache.axis2:axis2-spring

      @@ -1312,7 +1309,7 @@ -
      jar
      Newer versions1.5 Next Minor
      1.5.1
      1.5.2
      1.5.3
      1.5.4
      1.5.5
      1.5.6
      1.6.0
      1.6.1
      1.6.2
      1.6.3
      1.6.4
      1.7.0
      1.7.1 Latest Minor
      +1.5 Next Minor
      1.5.1
      1.5.2
      1.5.3
      1.5.4
      1.5.5
      1.5.6
      1.6.0
      1.6.1
      1.6.2
      1.6.3
      1.6.4
      1.7.0
      1.7.1
      1.7.2
      1.7.3 Latest Minor

      org.apache.commons:commons-compress

      @@ -1414,7 +1411,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-core

      @@ -1441,7 +1438,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1468,7 +1465,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1495,13 +1492,13 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.maven:maven-core

      - + @@ -1510,7 +1507,7 @@ - + @@ -1519,16 +1516,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-core
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-plugin-api

      - + @@ -1537,7 +1531,7 @@ - + @@ -1546,16 +1540,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-plugin-api
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-settings

      - + @@ -1564,7 +1555,7 @@ - + @@ -1573,10 +1564,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-settings
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven.plugin-testing:maven-plugin-testing-harness

      @@ -1729,7 +1717,7 @@ -
      jar
      Newer versions2.1.6 Next Incremental
      2.1.8
      2.1.8.1 Latest Incremental
      2.2.1 Next Minor
      2.2.1.1
      2.2.3
      2.2.3.1
      2.3.1
      2.3.1.1
      2.3.1.2
      2.3.3
      2.3.4
      2.3.4.1
      2.3.7
      2.3.8
      2.3.12
      2.3.14
      2.3.14.1
      2.3.14.2
      2.3.14.3
      2.3.15
      2.3.15.1
      2.3.15.2
      2.3.15.3
      2.3.16
      2.3.16.1
      2.3.16.2
      2.3.16.3
      2.3.20
      2.3.20.1
      2.3.24
      2.3.24.1
      2.3.28
      2.5-BETA1
      2.5-BETA2
      2.5-BETA3 Latest Minor
      +2.1.6 Next Incremental
      2.1.8
      2.1.8.1 Latest Incremental
      2.2.1 Next Minor
      2.2.1.1
      2.2.3
      2.2.3.1
      2.3.1
      2.3.1.1
      2.3.1.2
      2.3.3
      2.3.4
      2.3.4.1
      2.3.7
      2.3.8
      2.3.12
      2.3.14
      2.3.14.1
      2.3.14.2
      2.3.14.3
      2.3.15
      2.3.15.1
      2.3.15.2
      2.3.15.3
      2.3.16
      2.3.16.1
      2.3.16.2
      2.3.16.3
      2.3.20
      2.3.20.1
      2.3.20.3
      2.3.24
      2.3.24.1
      2.3.24.3
      2.3.28
      2.3.28.1
      2.5-BETA1
      2.5-BETA2
      2.5-BETA3
      2.5 Latest Minor

      org.apache.velocity:velocity

      @@ -1759,7 +1747,7 @@
      - + @@ -1780,7 +1768,7 @@ -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       There is at least one newer minor version available. Minor updates are sometimes passive.
      Group Id org.dojotoolkit
      war
      Newer versions1.3.1 Next Incremental
      1.3.2 Latest Incremental
      1.4.2 Next Minor
      1.4.3
      1.4.6
      1.5.0
      1.5.4
      1.6.0
      1.6.1
      1.6.3
      1.7.0
      1.7.1
      1.7.2
      1.7.8
      1.8.0
      1.8.1
      1.8.2
      1.8.3
      1.8.9
      1.9.0b2
      1.9.0
      1.9.1
      1.9.2
      1.9.3
      1.9.6
      1.10.0
      1.10.1
      1.10.2
      1.10.3
      1.10.4 Latest Minor
      +1.11.1 Next Minor

      org.glassfish:javax.json

      @@ -1861,7 +1849,7 @@
      - + @@ -1879,13 +1867,16 @@ -
      Status No newer versions available.
       There is at least one newer minor version available. Minor updates are sometimes passive.
      Group Id org.jmockit
      Typejar
      +jar + +Newer versions +1.23 Next Minor
      1.24 Latest Minor

      org.jsoup:jsoup

      - + @@ -1894,7 +1885,7 @@ - + @@ -1903,7 +1894,10 @@ -
      Status No newer versions available.
       There is at least one newer incremental version available. Incremental updates are typically passive.
      Group Id org.jsoup
      jsoup
      Current Version1.8.3
      1.9.1
      Scope
      Typejar
      +jar + +Newer versions +1.9.2 Next Incremental

      org.mortbay.jetty:jetty

      @@ -1945,7 +1939,7 @@ - + @@ -2053,7 +2047,7 @@ -
      dependency-check-utils
      Current Version1.3.6
      1.4.0
      Scope compile
      jar
      Newer versions2.5.6 Next Incremental
      2.5.6.SEC01
      2.5.6.SEC02
      2.5.6.SEC03 Latest Incremental
      3.0.0.RELEASE Next Major
      3.0.1.RELEASE
      3.0.2.RELEASE
      3.0.3.RELEASE
      3.0.4.RELEASE
      3.0.5.RELEASE
      3.0.6.RELEASE
      3.0.7.RELEASE
      3.1.0.RELEASE
      3.1.1.RELEASE
      3.1.2.RELEASE
      3.2.0.RELEASE
      3.2.1.RELEASE
      3.2.2.RELEASE
      3.2.3.RELEASE
      3.2.4.RELEASE
      3.2.5.RELEASE
      3.2.6.RELEASE
      3.2.7.RELEASE
      3.2.8.RELEASE
      3.2.9.RELEASE
      3.2.10.RELEASE
      3.2.11.RELEASE
      3.2.12.RELEASE
      3.2.13.RELEASE
      3.2.14.RELEASE
      3.2.15.RELEASE
      3.2.16.RELEASE
      4.0.0.RELEASE
      4.0.1.RELEASE
      4.0.2.RELEASE
      4.0.3.RELEASE
      4.0.4.RELEASE
      4.0.5.RELEASE
      4.0.6.RELEASE
      4.0.7.RELEASE
      4.0.8.RELEASE
      4.0.9.RELEASE
      4.1.0.RELEASE
      4.1.1.RELEASE
      4.1.2.RELEASE
      4.1.3.RELEASE
      4.1.4.RELEASE
      4.1.5.RELEASE
      4.1.6.RELEASE
      4.1.7.RELEASE
      4.1.8.RELEASE
      4.1.9.RELEASE
      4.2.0.RELEASE
      4.2.1.RELEASE
      4.2.2.RELEASE
      4.2.3.RELEASE
      4.2.4.RELEASE
      4.2.5.RELEASE Latest Major
      +2.5.6 Next Incremental
      2.5.6.SEC01
      2.5.6.SEC02
      2.5.6.SEC03 Latest Incremental
      3.0.0.RELEASE Next Major
      3.0.1.RELEASE
      3.0.2.RELEASE
      3.0.3.RELEASE
      3.0.4.RELEASE
      3.0.5.RELEASE
      3.0.6.RELEASE
      3.0.7.RELEASE
      3.1.0.RELEASE
      3.1.1.RELEASE
      3.1.2.RELEASE
      3.2.0.RELEASE
      3.2.1.RELEASE
      3.2.2.RELEASE
      3.2.3.RELEASE
      3.2.4.RELEASE
      3.2.5.RELEASE
      3.2.6.RELEASE
      3.2.7.RELEASE
      3.2.8.RELEASE
      3.2.9.RELEASE
      3.2.10.RELEASE
      3.2.11.RELEASE
      3.2.12.RELEASE
      3.2.13.RELEASE
      3.2.14.RELEASE
      3.2.15.RELEASE
      3.2.16.RELEASE
      3.2.17.RELEASE
      4.0.0.RELEASE
      4.0.1.RELEASE
      4.0.2.RELEASE
      4.0.3.RELEASE
      4.0.4.RELEASE
      4.0.5.RELEASE
      4.0.6.RELEASE
      4.0.7.RELEASE
      4.0.8.RELEASE
      4.0.9.RELEASE
      4.1.0.RELEASE
      4.1.1.RELEASE
      4.1.2.RELEASE
      4.1.3.RELEASE
      4.1.4.RELEASE
      4.1.5.RELEASE
      4.1.6.RELEASE
      4.1.7.RELEASE
      4.1.8.RELEASE
      4.1.9.RELEASE
      4.2.0.RELEASE
      4.2.1.RELEASE
      4.2.2.RELEASE
      4.2.3.RELEASE
      4.2.4.RELEASE
      4.2.5.RELEASE
      4.2.6.RELEASE
      4.3.0.RELEASE Latest Major

      org.springframework.retry:spring-retry

      @@ -2107,7 +2101,7 @@ -
      jar
      Newer versions3.0.1.RELEASE Next Incremental
      3.0.2.RELEASE
      3.0.3.RELEASE
      3.0.4.RELEASE
      3.0.5.RELEASE
      3.0.6.RELEASE
      3.0.7.RELEASE
      3.0.8.RELEASE Latest Incremental
      3.1.0.RELEASE Next Minor
      3.1.1.RELEASE
      3.1.2.RELEASE
      3.1.3.RELEASE
      3.1.4.RELEASE
      3.1.5.RELEASE
      3.1.6.RELEASE
      3.1.7.RELEASE
      3.2.0.RELEASE
      3.2.1.RELEASE
      3.2.2.RELEASE
      3.2.3.RELEASE
      3.2.4.RELEASE
      3.2.5.RELEASE
      3.2.6.RELEASE
      3.2.7.RELEASE
      3.2.8.RELEASE
      3.2.9.RELEASE Latest Minor
      4.0.0.RELEASE Next Major
      4.0.1.RELEASE
      4.0.2.RELEASE
      4.0.3.RELEASE
      4.0.4.RELEASE Latest Major
      +3.0.1.RELEASE Next Incremental
      3.0.2.RELEASE
      3.0.3.RELEASE
      3.0.4.RELEASE
      3.0.5.RELEASE
      3.0.6.RELEASE
      3.0.7.RELEASE
      3.0.8.RELEASE Latest Incremental
      3.1.0.RELEASE Next Minor
      3.1.1.RELEASE
      3.1.2.RELEASE
      3.1.3.RELEASE
      3.1.4.RELEASE
      3.1.5.RELEASE
      3.1.6.RELEASE
      3.1.7.RELEASE
      3.2.0.RELEASE
      3.2.1.RELEASE
      3.2.2.RELEASE
      3.2.3.RELEASE
      3.2.4.RELEASE
      3.2.5.RELEASE
      3.2.6.RELEASE
      3.2.7.RELEASE
      3.2.8.RELEASE
      3.2.9.RELEASE Latest Minor
      4.0.0.RELEASE Next Major
      4.0.1.RELEASE
      4.0.2.RELEASE
      4.0.3.RELEASE
      4.0.4.RELEASE
      4.1.0.RELEASE Latest Major

      uk.ltd.getahead:dwr

      diff --git a/dependency-check-core/failsafe-report.html b/dependency-check-core/failsafe-report.html index 03deb63f0..0dcbb56a2 100644 --- a/dependency-check-core/failsafe-report.html +++ b/dependency-check-core/failsafe-report.html @@ -1,13 +1,13 @@ - + dependency-check-core – Surefire Report @@ -52,7 +52,7 @@ @@ -228,9 +228,6 @@ developed using - - - built on cloudbees @@ -270,12 +267,12 @@ function toggleDisplay(elementId) { - + -
      Success Rate Time
      3637 0 0 0 100%143.237

      +179.157

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -296,7 +293,7 @@ function toggleDisplay(elementId) { 0 0 100% -1.219 +0.68 org.owasp.dependencycheck.reporting 2 @@ -304,7 +301,7 @@ function toggleDisplay(elementId) { 0 0 100% -6.977 +7.052 org.owasp.dependencycheck.data.update.nvd 1 @@ -312,15 +309,15 @@ function toggleDisplay(elementId) { 0 0 100% -25.83 +36.765 org.owasp.dependencycheck.data.nvdcve -9 +10 0 0 0 100% -6.156 +6.288 org.owasp.dependencycheck 1 @@ -328,7 +325,7 @@ function toggleDisplay(elementId) { 0 0 100% -71.83 +96.448 org.owasp.dependencycheck.analyzer 21 @@ -336,7 +333,7 @@ function toggleDisplay(elementId) { 0 0 100% -31.225
      +31.924

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.data.update

      @@ -358,7 +355,7 @@ function toggleDisplay(elementId) { 0 0 100% -0 +0.005 NvdCveUpdaterIntegrationTest @@ -367,7 +364,7 @@ function toggleDisplay(elementId) { 0 0 100% -1.219
      +0.675

      org.owasp.dependencycheck.reporting

      @@ -388,7 +385,7 @@ function toggleDisplay(elementId) { -
      0 0 100%6.977
      +7.052

      org.owasp.dependencycheck.data.update.nvd

      @@ -409,7 +406,7 @@ function toggleDisplay(elementId) { -
      0 0 100%25.83
      +36.765

      org.owasp.dependencycheck.data.nvdcve

      @@ -425,12 +422,12 @@ function toggleDisplay(elementId) { - + - + @@ -439,7 +436,7 @@ function toggleDisplay(elementId) { -
      CveDBIntegrationTest45 0 0 0 100%2.813
      3.18
      DatabasePropertiesIntegrationTest0 0 100%3.343
      +3.108

      org.owasp.dependencycheck

      @@ -460,7 +457,7 @@ function toggleDisplay(elementId) { -
      0 0 100%71.83
      +96.448

      org.owasp.dependencycheck.analyzer

      @@ -481,7 +478,7 @@ function toggleDisplay(elementId) { - + @@ -490,7 +487,7 @@ function toggleDisplay(elementId) { - + @@ -499,7 +496,7 @@ function toggleDisplay(elementId) { - + @@ -508,7 +505,7 @@ function toggleDisplay(elementId) { -
      0 0 100%23.749
      23.483
      CPEAnalyzerIntegrationTest0 0 100%5.144
      6.175
      DependencyBundlingAnalyzerIntegrationTest0 0 100%0
      0.003
      VulnerabilitySuppressionAnalyzerIntegrationTest0 0 100%2.332

      +2.263

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -518,19 +515,19 @@ function toggleDisplay(elementId) { testAnalyzeTar -5.274 +3.301 testAnalyzeTgz -5.381 +5.892 testAnalyzeTarBz2 -3.742 +4.492 testAnalyze -1.608 +1.985 testGetAnalysisPhase @@ -542,7 +539,7 @@ function toggleDisplay(elementId) { testAnalyze_badZip -0.526 +0.558 testInitialize @@ -550,11 +547,11 @@ function toggleDisplay(elementId) { testAnalyzeTbz2 -3.339 +3.19 testAnalyzeTarGz -3.144 +3.403 testSupportsExtension @@ -569,19 +566,19 @@ function toggleDisplay(elementId) { testSearchCPE -1.616 +1.722 testDetermineCPE -1.392 +1.505 testDetermineIdentifiers -0.91 +1.205 testDetermineCPE_full -1.224 +1.734 testBuildSearch @@ -599,7 +596,7 @@ function toggleDisplay(elementId) { testAnalyze -2.332 +2.256 testGetAnalysisPhase @@ -614,42 +611,46 @@ function toggleDisplay(elementId) { testOpen -1.05 +0.97 testGetCPEs -0.561 +0.485 testGetVulnerabilities -0.631 +0.715 testGetMatchingSoftware -0.567
      +0.495 + + +testgetVulnerability +0.513

      DatabasePropertiesIntegrationTest

      - + - + - + - + -
      testSave1.087
      1.11
      testGetProperty_String_String0.577
      0.499
      testGetProperties0.577
      0.495
      testGetProperty_String0.535
      0.491
      testIsEmpty0.567
      +0.508

      CpeUpdaterIntegrationTest

      @@ -663,32 +664,32 @@ function toggleDisplay(elementId) { -
      testUpdate25.83
      +36.759

      NvdCveUpdaterIntegrationTest

      -
      testUpdatesNeeded1.219
      +0.671

      EngineIntegrationTest

      -
      testEngine71.825
      +96.445

      ReportGeneratorIntegrationTest

      - + -
      testGenerateXMLReport6.976
      7.047
      testGenerateReport0

      +0.001
      diff --git a/dependency-check-core/findbugs.html b/dependency-check-core/findbugs.html index 65f3fdb97..5be51fca5 100644 --- a/dependency-check-core/findbugs.html +++ b/dependency-check-core/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-core – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ @@ -228,9 +228,6 @@ developed using - - - built on cloudbees @@ -254,7 +251,7 @@ Errors Missing Classes -133 +137 5 0 0 @@ -271,10 +268,10 @@ org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer 2 -org.owasp.dependencycheck.analyzer.JarAnalyzer +org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer 1 -org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer +org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer 1

      org.owasp.dependencycheck.analyzer.CMakeAnalyzer

      @@ -289,7 +286,7 @@ Found reliance on default encoding in org.owasp.dependencycheck.analyzer.CMakeAnalyzer.analyzeSetVersionCommand(Dependency, Engine, String): String.getBytes() I18N DM_DEFAULT_ENCODING -219 +221 High

      org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer

      @@ -311,21 +308,6 @@ STYLE NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE 188 -Medium
      -
      -

      org.owasp.dependencycheck.analyzer.JarAnalyzer

      - - - - - - - - - - - -
      BugCategoryDetailsLinePriority
      org.owasp.dependencycheck.analyzer.JarAnalyzer.parseManifest(Dependency, List) makes inefficient use of keySet iterator instead of entrySet iteratorPERFORMANCEWMI_WRONG_MAP_ITERATOR778 Medium

      org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer

      @@ -337,10 +319,25 @@ Line Priority -org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.analyzeFileType(Dependency, Engine) may fail to close stream +Exceptional return value of java.io.File.createNewFile() ignored in org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.createDependencyForGem(Engine, String, String, String, String) BAD_PRACTICE -OS_OPEN_STREAM -208 +RV_RETURN_VALUE_IGNORED_BAD_PRACTICE +459 +Medium
      +
      +

      org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer

      + + + + + + + + + + + +
      BugCategoryDetailsLinePriority
      Possible null pointer dereference in org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.addEvidenceFromVersionFile(File, EvidenceCollection) due to return value of called methodSTYLENP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE218 Medium
      diff --git a/dependency-check-core/index.html b/dependency-check-core/index.html index 67b4f2bef..0c191f85b 100644 --- a/dependency-check-core/index.html +++ b/dependency-check-core/index.html @@ -1,13 +1,13 @@ - + dependency-check-core – About @@ -52,7 +52,7 @@ @@ -128,9 +128,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-core/integration.html b/dependency-check-core/integration.html index b4a65433d..183bc6cf2 100644 --- a/dependency-check-core/integration.html +++ b/dependency-check-core/integration.html @@ -1,13 +1,13 @@ - + dependency-check-core – CI Management @@ -52,7 +52,7 @@ @@ -179,9 +179,6 @@ developed using - - - built on cloudbees @@ -192,11 +189,11 @@

      Overview

      -

      This project uses Continuous Integration System.

      +

      This project uses Travis CI.

      Access

      The following is a link to the continuous integration system used by the project:

      -
      +
      https://travis-ci.org/jeremylong/DependencyCheck

      Notifiers

      No notifiers are defined. Please check back at a later date.

      diff --git a/dependency-check-core/issue-tracking.html b/dependency-check-core/issue-tracking.html index 7c7da9c49..82582c82b 100644 --- a/dependency-check-core/issue-tracking.html +++ b/dependency-check-core/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-core – Issue Management @@ -52,7 +52,7 @@ @@ -179,9 +179,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-core/license.html b/dependency-check-core/license.html index 59da377d0..f32803dd1 100644 --- a/dependency-check-core/license.html +++ b/dependency-check-core/license.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Licenses @@ -52,7 +52,7 @@ @@ -179,9 +179,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-core/mail-lists.html b/dependency-check-core/mail-lists.html index 4d64a4147..8c48d0130 100644 --- a/dependency-check-core/mail-lists.html +++ b/dependency-check-core/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Mailing Lists @@ -52,7 +52,7 @@ @@ -179,9 +179,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-core/plugin-updates-report.html b/dependency-check-core/plugin-updates-report.html index b30020c09..77c18b95d 100644 --- a/dependency-check-core/plugin-updates-report.html +++ b/dependency-check-core/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-core – Plugin Updates Report @@ -52,7 +52,7 @@ @@ -228,9 +228,6 @@ developed using - - - built on cloudbees @@ -246,7 +243,7 @@ # of plugins using the latest version available -19 +18 # of plugins where the next version available is smaller than an incremental version update @@ -262,7 +259,7 @@ # of plugins where the next version available is a major version update -0 +1 # of plugins where a dependencies section containes a dependency with an updated version @@ -384,7 +381,7 @@ org.apache.maven.plugins maven-jar-plugin -2.6 +3.0.0 @@ -414,7 +411,7 @@ org.apache.maven.plugins maven-resources-plugin -2.7 +3.0.0 @@ -424,21 +421,21 @@ org.apache.maven.plugins maven-site-plugin -3.5 +3.5.1 - + org.apache.maven.plugins maven-source-plugin -2.4 - +2.4 +3.0.0 @@ -650,7 +647,7 @@ maven-jar-plugin Current Version -2.6 +3.0.0

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -695,7 +692,7 @@ -
      maven-resources-plugin
      Current Version2.7
      +3.0.0

      Plugin org.apache.maven.plugins:maven-site-plugin

      @@ -710,13 +707,13 @@ -
      maven-site-plugin
      Current Version3.5
      +3.5.1

      Plugin org.apache.maven.plugins:maven-source-plugin

      - + @@ -725,7 +722,10 @@ -
      Status No newer versions available.
       There is at least one newer major version available. Major updates are rarely passive.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      +2.4 + +Newer versions +3.0.0 Next Major

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-core/pmd.html b/dependency-check-core/pmd.html index a305652eb..2fbd00f91 100644 --- a/dependency-check-core/pmd.html +++ b/dependency-check-core/pmd.html @@ -1,13 +1,13 @@ - + dependency-check-core – PMD Results @@ -52,7 +52,7 @@ @@ -228,9 +228,6 @@ developed using - - - built on cloudbees @@ -252,13 +249,13 @@ - + - + -
      Line
      These nested if statements could be combined544549
      570575
      These nested if statements could be combined545548
      571574
      These nested if statements could be combined554557
      +579582

      org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.java

      @@ -288,7 +285,7 @@ -
      Line
      Useless parentheses.375
      +385

      org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java

      @@ -297,7 +294,7 @@ -
      Line
      Useless parentheses.77
      +111

      org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java

      @@ -306,7 +303,7 @@ -
      Line
      These nested if statements could be combined283286
      +284287

      org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java

      @@ -315,13 +312,13 @@ - + - + -
      Line
      These nested if statements could be combined263265
      337339
      Useless parentheses.271
      353
      Useless parentheses.282
      +371

      org/owasp/dependencycheck/data/cpe/IndexEntry.java

      @@ -360,10 +357,10 @@ - + -
      Line
      These nested if statements could be combined601603
      648650
      These nested if statements could be combined708710
      +760762

      org/owasp/dependencycheck/data/nvdcve/DriverShim.java

      @@ -381,7 +378,7 @@ -
      Line
      Useless parentheses.175
      +181

      org/owasp/dependencycheck/data/update/nvd/DownloadTask.java

      @@ -390,106 +387,103 @@ - - - -
      Line
      Useless parentheses.253
      Avoid empty catch blocks263264
      +253

      org/owasp/dependencycheck/dependency/Identifier.java

      - + - + - +
      Violation Line
      Useless parentheses. 191
      Useless parentheses. 194

      org/owasp/dependencycheck/dependency/Reference.java

      - + - - - - + -
      Violation Line
      Useless parentheses.109
      Useless parentheses.112
      115
      Useless parentheses.115
      +118 + +Useless parentheses. +121

      org/owasp/dependencycheck/dependency/Vulnerability.java

      - + - + -
      Violation Line
      Useless parentheses.373
      +375

      org/owasp/dependencycheck/dependency/VulnerableSoftware.java

      - + - - - - + + + +
      Violation Line
      Useless parentheses.141
      Useless parentheses.180
      141
      Useless parentheses.180
      Useless parentheses. 185

      org/owasp/dependencycheck/suppression/PropertyType.java

      - + - +
      Violation Line
      Useless parentheses. 161

      org/owasp/dependencycheck/utils/DependencyVersion.java

      - + - + - +
      Violation Line
      Useless parentheses. 136
      Useless parentheses. 197

      org/owasp/dependencycheck/xml/pom/License.java

      - + - + - +
      Violation Line
      Useless parentheses. 118
      Useless parentheses. 121

      org/owasp/dependencycheck/xml/pom/PomHandler.java

      - + - - - -
      Violation Line
      These nested if statements could be combined168174
      These nested if statements could be combined169173
      +170176 + +These nested if statements could be combined +171175 diff --git a/dependency-check-core/project-info.html b/dependency-check-core/project-info.html index 0a189ab3c..f283b1204 100644 --- a/dependency-check-core/project-info.html +++ b/dependency-check-core/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Information @@ -52,7 +52,7 @@ @@ -179,9 +179,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-core/project-reports.html b/dependency-check-core/project-reports.html index d50a2db45..4d0ac2656 100644 --- a/dependency-check-core/project-reports.html +++ b/dependency-check-core/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-core – Generated Reports @@ -52,7 +52,7 @@ @@ -228,9 +228,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-core/project-summary.html b/dependency-check-core/project-summary.html index 4fb3eb7ea..c7b0b3272 100644 --- a/dependency-check-core/project-summary.html +++ b/dependency-check-core/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Summary @@ -52,7 +52,7 @@ @@ -179,9 +179,6 @@ developed using - - - built on cloudbees @@ -233,7 +230,7 @@ dependency-check-core Version -1.3.6 +1.4.0 Type jar diff --git a/dependency-check-core/source-repository.html b/dependency-check-core/source-repository.html index e10325bec..ff0ee2254 100644 --- a/dependency-check-core/source-repository.html +++ b/dependency-check-core/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-core – Source Code Management @@ -52,7 +52,7 @@ @@ -179,9 +179,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-core/surefire-report.html b/dependency-check-core/surefire-report.html index fc6ceb75e..9e9b9240f 100644 --- a/dependency-check-core/surefire-report.html +++ b/dependency-check-core/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-core – Surefire Report @@ -52,7 +52,7 @@ @@ -228,9 +228,6 @@ developed using - - - built on cloudbees @@ -270,12 +267,12 @@ function toggleDisplay(elementId) { Success Rate Time -227 +242 0 0 -7 -96.916% -15.731
      +8 +96.694% +29.888

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -296,15 +293,15 @@ function toggleDisplay(elementId) { 0 0 100% -2.594 +2.394 org.owasp.dependencycheck.dependency -26 +34 0 0 0 100% -0.001 +0.016 org.owasp.dependencycheck.data.nexus 4 @@ -312,7 +309,7 @@ function toggleDisplay(elementId) { 0 4 0% -0 +0.019 org.owasp.dependencycheck.data.composer 4 @@ -320,7 +317,7 @@ function toggleDisplay(elementId) { 0 0 100% -0 +0.05 org.owasp.dependencycheck.suppression 36 @@ -328,7 +325,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.003 +0.037 org.owasp.dependencycheck.data.nuget 3 @@ -336,7 +333,7 @@ function toggleDisplay(elementId) { 0 0 100% -0 +0.003 org.owasp.dependencycheck.utils 13 @@ -344,15 +341,15 @@ function toggleDisplay(elementId) { 0 0 100% -0 +0.042 org.owasp.dependencycheck.analyzer -74 +80 0 0 -3 -95.946% -10.353 +4 +95% +24.286 org.owasp.dependencycheck.data.cpe 1 @@ -360,7 +357,7 @@ function toggleDisplay(elementId) { 0 0 100% -0 +0.013 org.owasp.dependencycheck.data.lucene 10 @@ -368,7 +365,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.684 +0.573 org.owasp.dependencycheck.data.cwe 1 @@ -376,15 +373,15 @@ function toggleDisplay(elementId) { 0 0 100% -0 +0.002 org.owasp.dependencycheck.data.update.nvd -14 +15 0 0 0 100% -1.089 +1.197 org.owasp.dependencycheck.xml.pom 23 @@ -392,7 +389,7 @@ function toggleDisplay(elementId) { 0 0 100% -0 +0.017 org.owasp.dependencycheck.data.nvdcve 7 @@ -400,7 +397,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.691 +1.236 org.owasp.dependencycheck.data.central 5 @@ -408,7 +405,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.316
      +0.003

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.data.update

      @@ -430,7 +427,7 @@ function toggleDisplay(elementId) { 0 0 100% -2.271 +2.123 EngineVersionCheckTest @@ -439,7 +436,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.323
      +0.271

      org.owasp.dependencycheck.dependency

      @@ -460,7 +457,7 @@ function toggleDisplay(elementId) { - + @@ -469,16 +466,25 @@ function toggleDisplay(elementId) { - + - - + + -
      0 0 100%0.001
      0.003
      EvidenceTest0 0 100%0
      0.005
      VulnerableSoftwareTestVulnerabilityTest 3 0 0 0 100%0
      +0.003 + + +VulnerableSoftwareTest +8 +0 +0 +0 +100% +0.005

      org.owasp.dependencycheck.data.nexus

      @@ -499,7 +505,7 @@ function toggleDisplay(elementId) { -
      0 4 0%0
      +0.019

      org.owasp.dependencycheck.data.composer

      @@ -520,7 +526,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0
      +0.05

      org.owasp.dependencycheck.suppression

      @@ -541,7 +547,7 @@ function toggleDisplay(elementId) { - + @@ -550,7 +556,7 @@ function toggleDisplay(elementId) { - + @@ -559,7 +565,7 @@ function toggleDisplay(elementId) { - + @@ -568,7 +574,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0
      0.003
      SuppressionHandlerTest0 0 100%0.001
      0.003
      SuppressionParserTest0 0 100%0.001
      0.015
      SuppressionRuleTest0 0 100%0.001
      +0.016

      org.owasp.dependencycheck.data.nuget

      @@ -589,7 +595,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0
      +0.003

      org.owasp.dependencycheck.utils

      @@ -610,7 +616,7 @@ function toggleDisplay(elementId) { - + @@ -619,7 +625,7 @@ function toggleDisplay(elementId) { - + @@ -628,7 +634,7 @@ function toggleDisplay(elementId) { - + @@ -637,7 +643,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0
      0.015
      DependencyVersionTest0 0 100%0
      0.022
      DependencyVersionUtilTest0 0 100%0
      0.003
      FilterTest0 0 100%0
      +0.002

      org.owasp.dependencycheck.analyzer

      @@ -658,7 +664,7 @@ function toggleDisplay(elementId) { - + @@ -667,16 +673,16 @@ function toggleDisplay(elementId) { - + - + - + @@ -685,7 +691,7 @@ function toggleDisplay(elementId) { - + @@ -694,7 +700,7 @@ function toggleDisplay(elementId) { - + @@ -703,7 +709,7 @@ function toggleDisplay(elementId) { - + @@ -712,7 +718,7 @@ function toggleDisplay(elementId) { - + @@ -721,7 +727,7 @@ function toggleDisplay(elementId) { - + @@ -730,7 +736,7 @@ function toggleDisplay(elementId) { - + @@ -739,7 +745,7 @@ function toggleDisplay(elementId) { - + @@ -748,7 +754,7 @@ function toggleDisplay(elementId) { - + @@ -757,7 +763,7 @@ function toggleDisplay(elementId) { - + @@ -766,7 +772,7 @@ function toggleDisplay(elementId) { - + @@ -775,7 +781,7 @@ function toggleDisplay(elementId) { - + @@ -784,7 +790,7 @@ function toggleDisplay(elementId) { - + @@ -793,7 +799,7 @@ function toggleDisplay(elementId) { - + @@ -802,7 +808,7 @@ function toggleDisplay(elementId) { - + @@ -811,17 +817,26 @@ function toggleDisplay(elementId) { - + - + - - - + + + + + + + + + + + + @@ -829,7 +844,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.878
      1.665
      AbstractSuppressionAnalyzerTest0 0 100%0.508
      1.012
      AnalyzerServiceTest12 0 0 0 100%0.075
      0.09
      ArchiveAnalyzerTest0 1 0%0.001
      0.043
      AssemblyAnalyzerTest0 1 80%0.809
      1.674
      AutoconfAnalyzerTest0 0 100%0.031
      0.165
      CMakeAnalyzerTest0 0 100%0.937
      1.092
      ComposerLockAnalyzerTest0 0 100%0.1
      1.39
      DependencyBundlingAnalyzerTest0 0 100%0.001
      0.003
      FalsePositiveAnalyzerTest0 0 100%0.001
      0.002
      FileNameAnalyzerTest0 0 100%0.001
      0.002
      HintAnalyzerTest0 0 100%4.82
      5.993
      JarAnalyzerTest0 0 100%0.131
      0.383
      NodePackageAnalyzerTest0 0 100%0
      0.004
      NuspecAnalyzerTest0 0 100%0
      0.004
      OpenSSLAnalyzerTest0 0 100%0.001
      0.005
      PythonDistributionAnalyzerTest0 0 100%2.037
      2.025
      PythonPackageAnalyzerTest0 0 100%0
      2.019
      RubyBundleAuditAnalyzerTest46 0 0175%0.022
      266.667%6.697
      RubyBundlerAnalyzerTest3000100%0.013
      RubyGemspecAnalyzerTest 30 0 100%0
      +0.005

      org.owasp.dependencycheck.data.cpe

      @@ -850,7 +865,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0
      +0.013

      org.owasp.dependencycheck.data.lucene

      @@ -871,7 +886,7 @@ function toggleDisplay(elementId) { - + @@ -880,7 +895,7 @@ function toggleDisplay(elementId) { - + @@ -889,7 +904,7 @@ function toggleDisplay(elementId) { - + @@ -898,7 +913,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0
      0.003
      LuceneUtilsTest0 0 100%0
      0.01
      TokenPairConcatenatingFilterTest0 0 100%0.222
      0.055
      UrlTokenizingFilterTest0 0 100%0.462
      +0.505

      org.owasp.dependencycheck.data.cwe

      @@ -919,7 +934,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0
      +0.002

      org.owasp.dependencycheck.data.update.nvd

      @@ -940,7 +955,7 @@ function toggleDisplay(elementId) { - + @@ -949,7 +964,7 @@ function toggleDisplay(elementId) { - + @@ -958,16 +973,16 @@ function toggleDisplay(elementId) { - + - + - + @@ -976,7 +991,7 @@ function toggleDisplay(elementId) { -
      0 0 100%1.057
      0.946
      NvdCveInfoTest0 0 100%0.016
      0.004
      NvdCve_1_2_HandlerTest0 0 100%0
      0.003
      NvdCve_2_0_HandlerTest12 0 0 0 100%0.015
      0.238
      UpdateableNvdCveTest0 0 100%0.001
      +0.006

      org.owasp.dependencycheck.xml.pom

      @@ -997,7 +1012,7 @@ function toggleDisplay(elementId) { - + @@ -1006,7 +1021,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0
      0.002
      PomUtilsTest0 0 100%0
      +0.015

      org.owasp.dependencycheck.data.nvdcve

      @@ -1027,7 +1042,7 @@ function toggleDisplay(elementId) { - + @@ -1036,7 +1051,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.522
      0.922
      DriverLoaderTest0 0 100%0.169
      +0.314

      org.owasp.dependencycheck.data.central

      @@ -1057,7 +1072,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.316

      +0.003

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -1067,33 +1082,37 @@ function toggleDisplay(elementId) { testNewHashSet -0.02
      +0.029

      AbstractSuppressionAnalyzerTest

      - + - + - + -
      testFailureToLocateSuppressionFileAnywhere0.293
      0.581
      testGetRulesFromSuppressionFileFromURL0.168
      0.356
      testGetRulesFromSuppressionFileInClasspath0.04
      0.068
      testGetSupportedExtensions0
      +0.002

      AnalyzerServiceTest

      -
      testGetAnalyzers0.075
      +0.08 + + +testGetExperimentalAnalyzers +0.007

      ArchiveAnalyzerTest

      @@ -1112,11 +1131,11 @@ function toggleDisplay(elementId) { - + - + - + -
      testGetName0.328
      0.545
      testAnalysis0.151
      0.296
      testWithSettingMono @@ -1129,18 +1148,18 @@ function toggleDisplay(elementId) {
      testNonexistent0.088
      0.212
      testLog4Net0.179
      +0.463

      AutoconfAnalyzerTest

      - + @@ -1152,15 +1171,15 @@ function toggleDisplay(elementId) { - + - + -
      testAnalyzeReadableConfigureScript0
      0.067
      testGetName
      testAnalyzeConfigureScript0.031
      0.073
      testAnalyzeConfigureAC10
      0.011
      testAnalyzeConfigureAC20
      +0.01

      CMakeAnalyzerTest

      @@ -1179,11 +1198,11 @@ function toggleDisplay(elementId) { - + -
      testAnalyzeCMakeListsOpenCV3rdParty0.936
      1.048
      testAccept0.001
      +0

      ComposerLockAnalyzerTest

      @@ -1194,11 +1213,11 @@ function toggleDisplay(elementId) { - + -
      testAnalyzePackageJson0.099
      1.384
      testSupportsFiles0.001
      +0

      DependencyBundlingAnalyzerTest

      @@ -1266,11 +1285,11 @@ function toggleDisplay(elementId) { - + - + @@ -1281,11 +1300,11 @@ function toggleDisplay(elementId) { - + - + @@ -1293,14 +1312,14 @@ function toggleDisplay(elementId) { -
      testAnalyze4.82
      5.985
      testGetAnalysisPhase0
      0.001
      testGetName
      testAnalyze0.1
      0.315
      testGetName0
      0.001
      testAcceptSupportedExtensions
      testParseManifest0.031
      +0.063

      NodePackageAnalyzerTest

      - + @@ -1361,11 +1380,11 @@ function toggleDisplay(elementId) { - + - + @@ -1373,11 +1392,11 @@ function toggleDisplay(elementId) { - + -
      testGetName0
      0.001
      testAnalyzePackageJson
      testAnalyzeEggArchiveNamedZip0.012
      0
      testAnalyzeWheel0.014
      0.005
      testAnalyzeEggInfoFolder
      testAnalyzeSitePackage0
      0.007
      testSupportsFiles0
      +0.003

      PythonPackageAnalyzerTest

      @@ -1399,7 +1418,7 @@ function toggleDisplay(elementId) { - + @@ -1415,9 +1434,37 @@ function toggleDisplay(elementId) { + + + + + + + + + + + +
      testMissingBundleAudit0
      0.617
      testGetName
      testDependenciesPath4.831
      testAddCriticalityToVulnerability +0
      skipped
      testSupportsFiles 0
      +

      RubyBundlerAnalyzerTest

      + + + + + + + + + + + + +
      testGetName0
      testAnalyzeGemspec0
      testSupportsFiles0
      +

      RubyGemspecAnalyzerTest

      @@ -1438,7 +1485,7 @@ function toggleDisplay(elementId) { - + @@ -1450,30 +1497,30 @@ function toggleDisplay(elementId) { - + -
      testMultipleReturns0.185
      0
      testNullSha1
      testValidSha10.069
      0
      testMissingSha10.062
      +0

      ComposerLockParserTest

      - + - + - + -
      testNotPackagesArray0
      0.003
      testValidComposerLock0
      0.017
      testNotComposer0
      0.005
      testNotJSON0
      +0.022

      IndexEntryTest

      @@ -1519,27 +1566,27 @@ function toggleDisplay(elementId) {
      - - + + - -
      testClear0.047
      testExamples0.037
      testExamples0
      +testClear +0.008

      UrlTokenizingFilterTest

      - - - - + + + + -
      testExamples0.046
      testEmptyTerm 0
      testExamples0.038
      testRandomStrings0.415
      +0.445

      NexusSearchTest

      @@ -1600,7 +1647,7 @@ function toggleDisplay(elementId) { -
      testInitialize0.522
      +0.916

      DriverLoaderTest

      @@ -1623,11 +1670,11 @@ function toggleDisplay(elementId) { - + -
      testLoad_String_String0.031
      0.041
      testLoad_String_String_multiple_paths0.138
      +0.254

      BaseUpdaterTest

      @@ -1638,37 +1685,37 @@ function toggleDisplay(elementId) { - + - + -
      testOpenDataStores1.107
      0.997
      testGetProperties0.586
      0.573
      testCloseDataStores0.578
      +0.549

      EngineVersionCheckTest

      - + -
      testShouldUpdate0.283
      0.234
      testGetCurrentReleaseVersion0.04
      +0.026

      DownloadTaskTest

      - + -
      testIsXML0.033
      0.013
      testCall1.009
      +0.93

      NvdCveInfoTest

      @@ -1683,7 +1730,7 @@ function toggleDisplay(elementId) { - + @@ -1704,8 +1751,12 @@ function toggleDisplay(elementId) {
      testSetGetOldSchemaVersionUrl0.016
      0
      testSetGetUrl
      + + + + -
      testParserWithPreviousVersion0
      testParse0
      +0.235

      UpdateableNvdCveTest

      @@ -1799,7 +1850,7 @@ function toggleDisplay(elementId) { - + @@ -1828,10 +1879,33 @@ function toggleDisplay(elementId) {
      testGetEvidence0
      0.001
      testSetIdentifierstestEquals 0
      +

      VulnerabilityTest

      + + + + + + + + + + + + +
      testDuplicateVersions0
      testDpulicateVersionsWithPreviousVersion0
      testSoftwareSorting0
      +

      VulnerableSoftwareTest

      + + + + + + + + @@ -1840,7 +1914,19 @@ function toggleDisplay(elementId) { + + + + + + + + + + + +
      testEquals20
      testCompareToNonNumerical0
      testCompareTo 0
      0
      testEqualsPreviousVersion0
      testEquals0
      testCompareToComplex0
      testParseCPE 0

      PropertyTypeTest

      @@ -2184,6 +2270,12 @@ function toggleDisplay(elementId) { skipped: skipped +testAddCriticalityToVulnerability + + +skipped: skipped + + testNullSha1 diff --git a/dependency-check-core/taglist.html b/dependency-check-core/taglist.html index 57b4c63db..81efb0e37 100644 --- a/dependency-check-core/taglist.html +++ b/dependency-check-core/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-core – Tag List report @@ -52,7 +52,7 @@ @@ -228,9 +228,6 @@ developed using - - - built on cloudbees
      @@ -249,12 +246,12 @@ Tag strings used by tag class Todo Work -21 +25 todo, FIXME

      Each tag is detailed below:

      Todo Work

      -

      Number of occurrences found in the code: 21

      +

      Number of occurrences found in the code: 25

      @@ -267,52 +264,70 @@ - + - + - + - + - - + + + + + - + - + - + - + - + - + - + - - - + + + - + + + + + + + + + + + + + + + + @@ -348,16 +363,16 @@ - + - + -
      org.owasp.dependencycheck.analyzer.ArchiveAnalyzerLine
      - refactor so we do not assign to the parameter (checkstyle)209
      211
      org.owasp.dependencycheck.analyzer.CPEAnalyzer Line
      test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit182
      188
      - does this nullify some of the fuzzy matching that happens in the lucene search? for instance CPE some-component and in the evidence we have SomeComponent.419
      439
      - likely need to change the split... not sure if this will work for CPE with special chars437
      457
      the following isn't quite right is it? need to think about this guessing game a bit more.541
      the following algorithm incorrectly identifies things as a lower version if there lower confidence evidence when the current (highest) version number is newer then anything in the NVD.542
      the following isn't quite right is it? need to think about this guessing game a bit more.567
      org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzerTest Line
      review the generated test code and remove the default call to fail. fail("The test case is a prototype."); 62
      org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer Line
      fix the version problem below 175
      - can we utilize the pom's groupid and artifactId to filter??? most of these are due to low quality data. Other idea would be to say any CPE found based on LOW confidence evidence should have a different CPE type? (this might be a better solution then just removing the URL for "best-guess" matches). 276
      move this startsWith expression to the base suppression file 285
      move this to the hint analyzer 382
      org.owasp.dependencycheck.analyzer.JarAnalyzer Line
      remove weighting594
      remove weighting613
      change this to a regex?713
      728
      org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzerLine
      support Rakefile = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();74
      other checking?221
      org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzerTestLine
      add verification114
      org.owasp.dependencycheck.data.nvdcve.ConnectionFactory Line
      Line
      (code review): should this be here/do something? assertEquals("0", parts.get(2));53
      54
      org.owasp.dependencycheck.xml.pom.PomHandler Line
      add error logging165
      167
      add error logging172
      +174 diff --git a/dependency-check-core/team-list.html b/dependency-check-core/team-list.html index 7b3243d71..37ffcf49e 100644 --- a/dependency-check-core/team-list.html +++ b/dependency-check-core/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Team @@ -52,7 +52,7 @@ @@ -179,9 +179,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-core/xref-test/allclasses-frame.html b/dependency-check-core/xref-test/allclasses-frame.html index 28344e306..79ce705c5 100644 --- a/dependency-check-core/xref-test/allclasses-frame.html +++ b/dependency-check-core/xref-test/allclasses-frame.html @@ -181,6 +181,9 @@
    50. RubyBundleAuditAnalyzerTest +
    51. +
    52. + RubyBundlerAnalyzerTest
    53. RubyGemspecAnalyzerTest @@ -205,6 +208,9 @@
    54. VulnerabilitySuppressionAnalyzerIntegrationTest +
    55. +
    56. + VulnerabilityTest
    57. VulnerableSoftwareTest diff --git a/dependency-check-core/xref-test/index.html b/dependency-check-core/xref-test/index.html index bb6a4037a..e71e8ba73 100644 --- a/dependency-check-core/xref-test/index.html +++ b/dependency-check-core/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Core 1.3.6 Reference + Dependency-Check Core 1.4.0 Reference diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseDBTestCase.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseDBTestCase.html index ba1377c61..8567f8f5d 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseDBTestCase.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseDBTestCase.html @@ -39,8 +39,8 @@ 31 import org.slf4j.LoggerFactory; 32 33 /** -34 * An abstract database test case that is used to ensure the H2 DB exists prior to performing tests that utilize the data -35 * contained within. +34 * An abstract database test case that is used to ensure the H2 DB exists prior +35 * to performing tests that utilize the data contained within. 36 * 37 * @author Jeremy Long 38 */ @@ -57,78 +57,83 @@ 49 50 public static void ensureDBExists() throws Exception { 51 -52 java.io.File dataPath = Settings.getDataDirectory(); -53 String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME); -54 LOGGER.trace("DB file name {}", fileName); -55 java.io.File dataFile = new File(dataPath, fileName); -56 LOGGER.trace("Ensuring {} exists", dataFile.toString()); -57 if (!dataPath.exists() || !dataFile.exists()) { -58 LOGGER.trace("Extracting database to {}", dataPath.toString()); -59 dataPath.mkdirs(); -60 FileInputStream fis = null; -61 ZipInputStream zin = null; -62 try { -63 File path = new File(BaseDBTestCase.class.getClassLoader().getResource("data.zip").getPath()); -64 fis = new FileInputStream(path); -65 zin = new ZipInputStream(new BufferedInputStream(fis)); -66 ZipEntry entry; -67 while ((entry = zin.getNextEntry()) != null) { -68 if (entry.isDirectory()) { -69 final File d = new File(dataPath, entry.getName()); -70 d.mkdir(); -71 continue; -72 } -73 FileOutputStream fos = null; -74 BufferedOutputStream dest = null; -75 try { -76 File o = new File(dataPath, entry.getName()); -77 o.createNewFile(); -78 fos = new FileOutputStream(o, false); -79 dest = new BufferedOutputStream(fos, BUFFER_SIZE); -80 byte data[] = new byte[BUFFER_SIZE]; -81 int count; -82 while ((count = zin.read(data, 0, BUFFER_SIZE)) != -1) { -83 dest.write(data, 0, count); -84 } -85 } catch (Throwable ex) { -86 LOGGER.error("", ex); -87 } finally { -88 try { -89 if (dest != null) { -90 dest.flush(); -91 dest.close(); -92 } -93 } catch (Throwable ex) { -94 LOGGER.trace("", ex); -95 } -96 try { -97 if (fos != null) { -98 fos.close(); -99 } -100 } catch (Throwable ex) { -101 LOGGER.trace("", ex); -102 } -103 } -104 } -105 } finally { -106 try { -107 if (zin != null) { -108 zin.close(); -109 } -110 } catch (Throwable ex) { -111 LOGGER.trace("", ex); -112 } -113 try { -114 if (fis != null) { -115 fis.close(); -116 } -117 } catch (Throwable ex) { -118 LOGGER.trace("", ex); -119 } -120 } -121 } -122 } -123 } +52 File f = new File("./target/data/dc.h2.db"); +53 if (f.exists() && f.isFile() && f.length() < 71680) { +54 f.delete(); +55 } +56 +57 java.io.File dataPath = Settings.getDataDirectory(); +58 String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME); +59 LOGGER.trace("DB file name {}", fileName); +60 java.io.File dataFile = new File(dataPath, fileName); +61 LOGGER.trace("Ensuring {} exists", dataFile.toString()); +62 if (!dataPath.exists() || !dataFile.exists()) { +63 LOGGER.trace("Extracting database to {}", dataPath.toString()); +64 dataPath.mkdirs(); +65 FileInputStream fis = null; +66 ZipInputStream zin = null; +67 try { +68 File path = new File(BaseDBTestCase.class.getClassLoader().getResource("data.zip").getPath()); +69 fis = new FileInputStream(path); +70 zin = new ZipInputStream(new BufferedInputStream(fis)); +71 ZipEntry entry; +72 while ((entry = zin.getNextEntry()) != null) { +73 if (entry.isDirectory()) { +74 final File d = new File(dataPath, entry.getName()); +75 d.mkdir(); +76 continue; +77 } +78 FileOutputStream fos = null; +79 BufferedOutputStream dest = null; +80 try { +81 File o = new File(dataPath, entry.getName()); +82 o.createNewFile(); +83 fos = new FileOutputStream(o, false); +84 dest = new BufferedOutputStream(fos, BUFFER_SIZE); +85 byte data[] = new byte[BUFFER_SIZE]; +86 int count; +87 while ((count = zin.read(data, 0, BUFFER_SIZE)) != -1) { +88 dest.write(data, 0, count); +89 } +90 } catch (Throwable ex) { +91 LOGGER.error("", ex); +92 } finally { +93 try { +94 if (dest != null) { +95 dest.flush(); +96 dest.close(); +97 } +98 } catch (Throwable ex) { +99 LOGGER.trace("", ex); +100 } +101 try { +102 if (fos != null) { +103 fos.close(); +104 } +105 } catch (Throwable ex) { +106 LOGGER.trace("", ex); +107 } +108 } +109 } +110 } finally { +111 try { +112 if (zin != null) { +113 zin.close(); +114 } +115 } catch (Throwable ex) { +116 LOGGER.trace("", ex); +117 } +118 try { +119 if (fis != null) { +120 fis.close(); +121 } +122 } catch (Throwable ex) { +123 LOGGER.trace("", ex); +124 } +125 } +126 } +127 } +128 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseTest.html index 2ad508041..30448c552 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseTest.html @@ -47,7 +47,7 @@ 39 if (f.exists() && f.isFile() && f.length() < 71680) { 40 System.err.println("------------------------------------------------"); 41 System.err.println("------------------------------------------------"); -42 System.err.println("I broke the build"); +42 System.err.println("Test referenced CveDB() and does not extend BaseDbTestCases?"); 43 System.err.println("------------------------------------------------"); 44 System.err.println("------------------------------------------------"); 45 } diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html index 0a3dc6eb2..eac332370 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html @@ -38,41 +38,32 @@ 30 * 31 * @author Jeremy Long 32 */ -33 public class EngineIntegrationTest extends BaseTest { +33 public class EngineIntegrationTest extends BaseDBTestCase { 34 -35 @Before -36 public void setUp() throws Exception { -37 org.owasp.dependencycheck.BaseDBTestCase.ensureDBExists(); -38 } -39 -40 @After -41 public void tearDown() { -42 } -43 -44 /** -45 * Test running the entire engine. -46 * -47 * @throws Exception is thrown when an exception occurs. -48 */ -49 @Test -50 public void testEngine() throws Exception { -51 String testClasses = "target/test-classes"; -52 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -53 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -54 Engine instance = new Engine(); -55 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -56 instance.scan(testClasses); -57 assertTrue(instance.getDependencies().size() > 0); -58 instance.analyzeDependencies(); -59 CveDB cveDB = new CveDB(); -60 cveDB.open(); -61 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); -62 cveDB.close(); -63 ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); -64 rg.generateReports("./target/", "ALL"); -65 instance.cleanup(); -66 } -67 } +35 /** +36 * Test running the entire engine. +37 * +38 * @throws Exception is thrown when an exception occurs. +39 */ +40 @Test +41 public void testEngine() throws Exception { +42 String testClasses = "target/test-classes"; +43 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +44 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +45 Engine instance = new Engine(); +46 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +47 instance.scan(testClasses); +48 assertTrue(instance.getDependencies().size() > 0); +49 instance.analyzeDependencies(); +50 CveDB cveDB = new CveDB(); +51 cveDB.open(); +52 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); +53 cveDB.close(); +54 ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); +55 rg.generateReports("./target/", "ALL"); +56 instance.cleanup(); +57 } +58 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html index 0891773b9..b19c56d9a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html @@ -85,8 +85,8 @@ 77 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml"); 78 instance.initialize(); 79 int expCount = 5; -80 List<SuppressionRule> result = instance.getRules(); -81 assertTrue(expCount <= result.size()); +80 int currentSize = instance.getRules().size(); +81 assertTrue(expCount <= currentSize); 82 } 83 84 @Test(expected = SuppressionParseException.class) diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html index 771cecd1a..678736ff6 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html @@ -26,34 +26,64 @@ 18 package org.owasp.dependencycheck.analyzer; 19 20 import java.util.Iterator; -21 import static org.junit.Assert.assertTrue; -22 import org.junit.Test; -23 import org.owasp.dependencycheck.BaseTest; -24 -25 /** -26 * -27 * @author Jeremy Long -28 */ -29 public class AnalyzerServiceTest extends BaseTest { -30 -31 /** -32 * Test of getAnalyzers method, of class AnalyzerService. -33 */ -34 @Test -35 public void testGetAnalyzers() { -36 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); -37 Iterator<Analyzer> result = instance.getAnalyzers(); -38 -39 boolean found = false; -40 while (result.hasNext()) { -41 Analyzer a = result.next(); -42 if ("Jar Analyzer".equals(a.getName())) { -43 found = true; -44 } -45 } -46 assertTrue("JarAnalyzer loaded", found); -47 } -48 } +21 import java.util.List; +22 import static org.junit.Assert.assertFalse; +23 import static org.junit.Assert.assertTrue; +24 import org.junit.Test; +25 import org.owasp.dependencycheck.BaseDBTestCase; +26 import org.owasp.dependencycheck.utils.Settings; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public class AnalyzerServiceTest extends BaseDBTestCase { +33 +34 /** +35 * Test of getAnalyzers method, of class AnalyzerService. +36 */ +37 @Test +38 public void testGetAnalyzers() { +39 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); +40 List<Analyzer> result = instance.getAnalyzers(); +41 +42 boolean found = false; +43 for (Analyzer a : result) { +44 if ("Jar Analyzer".equals(a.getName())) { +45 found = true; +46 } +47 } +48 assertTrue("JarAnalyzer loaded", found); +49 } +50 +51 /** +52 * Test of getAnalyzers method, of class AnalyzerService. +53 */ +54 @Test +55 public void testGetExperimentalAnalyzers() { +56 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); +57 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); +58 List<Analyzer> result = instance.getAnalyzers(); +59 String experimental = "CMake Analyzer"; +60 boolean found = false; +61 for (Analyzer a : result) { +62 if (experimental.equals(a.getName())) { +63 found = true; +64 } +65 } +66 assertFalse("Experimental analyzer loaded when set to false", found); +67 +68 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, true); +69 result = instance.getAnalyzers(); +70 found = false; +71 for (Analyzer a : result) { +72 if (experimental.equals(a.getName())) { +73 found = true; +74 } +75 } +76 assertTrue("Experimental analyzer not loaded when set to true", found); +77 } +78 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html index 6ada26cb3..036e178cb 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html @@ -248,7 +248,7 @@ 240 241 Set<String> vendorWeightings = Collections.singleton("apache"); 242 -243 List<IndexEntry> result = instance.searchCPE(vendor, product, productWeightings, vendorWeightings); +243 List<IndexEntry> result = instance.searchCPE(vendor, product, vendorWeightings, productWeightings); 244 instance.close(); 245 246 boolean found = false; diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html index f51f1e85a..2a4d163ba 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html @@ -63,51 +63,52 @@ 55 */ 56 @Before 57 public void setUp() throws Exception { -58 analyzer = new ComposerLockAnalyzer(); -59 analyzer.setFilesMatched(true); -60 analyzer.initialize(); -61 } -62 -63 /** -64 * Cleanup the analyzer's temp files, etc. -65 * -66 * @throws Exception thrown if there is a problem -67 */ -68 @After -69 public void tearDown() throws Exception { -70 analyzer.close(); -71 analyzer = null; -72 } -73 -74 /** -75 * Test of getName method, of class ComposerLockAnalyzer. -76 */ -77 @Test -78 public void testGetName() { -79 assertEquals("Composer.lock analyzer", analyzer.getName()); -80 } -81 -82 /** -83 * Test of supportsExtension method, of class ComposerLockAnalyzer. -84 */ -85 @Test -86 public void testSupportsFiles() { -87 assertTrue(analyzer.accept(new File("composer.lock"))); -88 } -89 -90 /** -91 * Test of inspect method, of class PythonDistributionAnalyzer. -92 * -93 * @throws AnalysisException is thrown when an exception occurs. -94 */ -95 @Test -96 public void testAnalyzePackageJson() throws Exception { -97 final Engine engine = new Engine(); -98 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, -99 "composer.lock")); -100 analyzer.analyze(result, engine); -101 } -102 } +58 super.setUp(); +59 analyzer = new ComposerLockAnalyzer(); +60 analyzer.setFilesMatched(true); +61 analyzer.initialize(); +62 } +63 +64 /** +65 * Cleanup the analyzer's temp files, etc. +66 * +67 * @throws Exception thrown if there is a problem +68 */ +69 @After +70 public void tearDown() throws Exception { +71 analyzer.close(); +72 analyzer = null; +73 } +74 +75 /** +76 * Test of getName method, of class ComposerLockAnalyzer. +77 */ +78 @Test +79 public void testGetName() { +80 assertEquals("Composer.lock analyzer", analyzer.getName()); +81 } +82 +83 /** +84 * Test of supportsExtension method, of class ComposerLockAnalyzer. +85 */ +86 @Test +87 public void testSupportsFiles() { +88 assertTrue(analyzer.accept(new File("composer.lock"))); +89 } +90 +91 /** +92 * Test of inspect method, of class PythonDistributionAnalyzer. +93 * +94 * @throws AnalysisException is thrown when an exception occurs. +95 */ +96 @Test +97 public void testAnalyzePackageJson() throws Exception { +98 final Engine engine = new Engine(); +99 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +100 "composer.lock")); +101 analyzer.analyze(result, engine); +102 } +103 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.html index cbd99ed40..0ece9936c 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.html @@ -26,55 +26,56 @@ 18 import static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertTrue; 20 import org.junit.Test; -21 import org.owasp.dependencycheck.Engine; -22 import org.owasp.dependencycheck.dependency.Dependency; -23 -24 /** -25 * -26 * @author Jeremy Long -27 */ -28 public class FalsePositiveAnalyzerTest { -29 -30 /** -31 * Test of getName method, of class FalsePositiveAnalyzer. -32 */ -33 @Test -34 public void testGetName() { -35 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); -36 String expResult = "False Positive Analyzer"; -37 String result = instance.getName(); -38 assertEquals(expResult, result); -39 } -40 -41 /** -42 * Test of getAnalysisPhase method, of class FalsePositiveAnalyzer. -43 */ -44 @Test -45 public void testGetAnalysisPhase() { -46 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); -47 AnalysisPhase expResult = AnalysisPhase.POST_IDENTIFIER_ANALYSIS; -48 AnalysisPhase result = instance.getAnalysisPhase(); -49 assertEquals(expResult, result); -50 } -51 -52 /** -53 * Test of analyze method, of class FalsePositiveAnalyzer. -54 */ -55 @Test -56 public void testAnalyze() throws Exception { -57 Dependency dependency = new Dependency(); -58 dependency.setFileName("pom.xml"); -59 dependency.setFilePath("pom.xml"); -60 dependency.addIdentifier("cpe", "cpe:/a:file:file:1.2.1", "http://some.org/url"); -61 Engine engine = null; -62 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); -63 int before = dependency.getIdentifiers().size(); -64 instance.analyze(dependency, engine); -65 int after = dependency.getIdentifiers().size(); -66 assertTrue(before > after); -67 } -68 -69 } +21 import org.owasp.dependencycheck.BaseTest; +22 import org.owasp.dependencycheck.Engine; +23 import org.owasp.dependencycheck.dependency.Dependency; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class FalsePositiveAnalyzerTest extends BaseTest { +30 +31 /** +32 * Test of getName method, of class FalsePositiveAnalyzer. +33 */ +34 @Test +35 public void testGetName() { +36 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); +37 String expResult = "False Positive Analyzer"; +38 String result = instance.getName(); +39 assertEquals(expResult, result); +40 } +41 +42 /** +43 * Test of getAnalysisPhase method, of class FalsePositiveAnalyzer. +44 */ +45 @Test +46 public void testGetAnalysisPhase() { +47 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); +48 AnalysisPhase expResult = AnalysisPhase.POST_IDENTIFIER_ANALYSIS; +49 AnalysisPhase result = instance.getAnalysisPhase(); +50 assertEquals(expResult, result); +51 } +52 +53 /** +54 * Test of analyze method, of class FalsePositiveAnalyzer. +55 */ +56 @Test +57 public void testAnalyze() throws Exception { +58 Dependency dependency = new Dependency(); +59 dependency.setFileName("pom.xml"); +60 dependency.setFilePath("pom.xml"); +61 dependency.addIdentifier("cpe", "cpe:/a:file:file:1.2.1", "http://some.org/url"); +62 Engine engine = null; +63 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); +64 int before = dependency.getIdentifiers().size(); +65 instance.analyze(dependency, engine); +66 int after = dependency.getIdentifiers().size(); +67 assertTrue(before > after); +68 } +69 +70 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.html index 3d0554733..0e00d4786 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.html @@ -36,7 +36,7 @@ 28 * 29 * @author Jeremy Long 30 */ -31 public class FileNameAnalyzerTest { +31 public class FileNameAnalyzerTest extends BaseTest { 32 33 /** 34 * Test of getName method, of class FileNameAnalyzer. diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/JarAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/JarAnalyzerTest.html index c3ab8d23a..69a15ad1a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/JarAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/JarAnalyzerTest.html @@ -25,115 +25,130 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import org.junit.Test; -21 import org.owasp.dependencycheck.BaseTest; -22 import org.owasp.dependencycheck.dependency.Dependency; -23 import org.owasp.dependencycheck.dependency.Evidence; -24 -25 import java.io.File; -26 import java.util.ArrayList; -27 import java.util.List; -28 -29 import static org.junit.Assert.assertEquals; -30 import static org.junit.Assert.assertTrue; +20 import static org.junit.Assert.assertEquals; +21 import static org.junit.Assert.assertTrue; +22 +23 import java.io.File; +24 import java.util.ArrayList; +25 import java.util.List; +26 +27 import org.junit.Test; +28 import org.owasp.dependencycheck.BaseTest; +29 import org.owasp.dependencycheck.dependency.Dependency; +30 import org.owasp.dependencycheck.dependency.Evidence; 31 32 /** 33 * @author Jeremy Long 34 */ 35 public class JarAnalyzerTest extends BaseTest { 36 -37 /** -38 * Test of inspect method, of class JarAnalyzer. -39 * -40 * @throws Exception is thrown when an exception occurs. -41 */ -42 @Test -43 public void testAnalyze() throws Exception { -44 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -45 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -46 Dependency result = new Dependency(file); -47 JarAnalyzer instance = new JarAnalyzer(); -48 instance.analyze(result, null); -49 assertTrue(result.getVendorEvidence().toString().toLowerCase().contains("apache")); -50 assertTrue(result.getVendorEvidence().getWeighting().contains("apache")); -51 -52 //file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); -53 file = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar"); -54 result = new Dependency(file); -55 instance.analyze(result, null); -56 boolean found = false; -57 for (Evidence e : result.getProductEvidence()) { -58 if (e.getName().equalsIgnoreCase("package-title") -59 && e.getValue().equalsIgnoreCase("org.mortbay.http")) { -60 found = true; -61 break; -62 } -63 } -64 assertTrue("package-title of org.mortbay.http not found in org.mortbay.jetty.jar", found); -65 -66 found = false; -67 for (Evidence e : result.getVendorEvidence()) { -68 if (e.getName().equalsIgnoreCase("implementation-url") -69 && e.getValue().equalsIgnoreCase("http://jetty.mortbay.org")) { -70 found = true; -71 break; -72 } -73 } -74 assertTrue("implementation-url of http://jetty.mortbay.org not found in org.mortbay.jetty.jar", found); -75 -76 found = false; -77 for (Evidence e : result.getVersionEvidence()) { -78 if (e.getName().equalsIgnoreCase("Implementation-Version") -79 && e.getValue().equalsIgnoreCase("4.2.27")) { -80 found = true; -81 break; -82 } -83 } -84 assertTrue("implementation-version of 4.2.27 not found in org.mortbay.jetty.jar", found); -85 -86 //file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jmx.jar").getPath()); -87 file = BaseTest.getResourceAsFile(this, "org.mortbay.jmx.jar"); -88 result = new Dependency(file); -89 instance.analyze(result, null); -90 assertEquals("org.mortbar.jmx.jar has version evidence?", result.getVersionEvidence().size(), 0); -91 } -92 -93 /** -94 * Test of getSupportedExtensions method, of class JarAnalyzer. -95 */ -96 @Test -97 public void testAcceptSupportedExtensions() throws Exception { -98 JarAnalyzer instance = new JarAnalyzer(); -99 instance.initialize(); -100 instance.setEnabled(true); -101 String[] files = {"test.jar", "test.war"}; -102 for (String name : files) { -103 assertTrue(name, instance.accept(new File(name))); -104 } -105 } -106 -107 /** -108 * Test of getName method, of class JarAnalyzer. -109 */ -110 @Test -111 public void testGetName() { -112 JarAnalyzer instance = new JarAnalyzer(); -113 String expResult = "Jar Analyzer"; -114 String result = instance.getName(); -115 assertEquals(expResult, result); -116 } -117 -118 @Test -119 public void testParseManifest() throws Exception { -120 File file = BaseTest.getResourceAsFile(this, "xalan-2.7.0.jar"); -121 Dependency result = new Dependency(file); -122 JarAnalyzer instance = new JarAnalyzer(); -123 List<JarAnalyzer.ClassNameInformation> cni = new ArrayList<JarAnalyzer.ClassNameInformation>(); -124 instance.parseManifest(result, cni); -125 -126 assertTrue(result.getVersionEvidence().getEvidence("manifest: org/apache/xalan/").size() > 0); -127 } -128 } +37 // private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzerTest.class); +38 +39 /** +40 * Test of inspect method, of class JarAnalyzer. +41 * +42 * @throws Exception is thrown when an exception occurs. +43 */ +44 @Test +45 public void testAnalyze() throws Exception { +46 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +47 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +48 Dependency result = new Dependency(file); +49 JarAnalyzer instance = new JarAnalyzer(); +50 instance.analyze(result, null); +51 assertTrue(result.getVendorEvidence().toString().toLowerCase().contains("apache")); +52 assertTrue(result.getVendorEvidence().getWeighting().contains("apache")); +53 +54 file = BaseTest.getResourceAsFile(this, "dwr.jar"); +55 result = new Dependency(file); +56 instance.analyze(result, null); +57 boolean found = false; +58 for (Evidence e : result.getVendorEvidence()) { +59 if (e.getName().equals("url")) { +60 assertEquals("Project url was not as expected in dwr.jar", e.getValue(), "http://getahead.ltd.uk/dwr"); +61 found = true; +62 break; +63 } +64 } +65 assertTrue("Project url was not found in dwr.jar", found); +66 +67 //file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); +68 file = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar"); +69 result = new Dependency(file); +70 instance.analyze(result, null); +71 found = false; +72 for (Evidence e : result.getProductEvidence()) { +73 if (e.getName().equalsIgnoreCase("package-title") +74 && e.getValue().equalsIgnoreCase("org.mortbay.http")) { +75 found = true; +76 break; +77 } +78 } +79 assertTrue("package-title of org.mortbay.http not found in org.mortbay.jetty.jar", found); +80 +81 found = false; +82 for (Evidence e : result.getVendorEvidence()) { +83 if (e.getName().equalsIgnoreCase("implementation-url") +84 && e.getValue().equalsIgnoreCase("http://jetty.mortbay.org")) { +85 found = true; +86 break; +87 } +88 } +89 assertTrue("implementation-url of http://jetty.mortbay.org not found in org.mortbay.jetty.jar", found); +90 +91 found = false; +92 for (Evidence e : result.getVersionEvidence()) { +93 if (e.getName().equalsIgnoreCase("Implementation-Version") +94 && e.getValue().equalsIgnoreCase("4.2.27")) { +95 found = true; +96 break; +97 } +98 } +99 assertTrue("implementation-version of 4.2.27 not found in org.mortbay.jetty.jar", found); +100 +101 //file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jmx.jar").getPath()); +102 file = BaseTest.getResourceAsFile(this, "org.mortbay.jmx.jar"); +103 result = new Dependency(file); +104 instance.analyze(result, null); +105 assertEquals("org.mortbar.jmx.jar has version evidence?", result.getVersionEvidence().size(), 0); +106 } +107 +108 /** +109 * Test of getSupportedExtensions method, of class JarAnalyzer. +110 */ +111 @Test +112 public void testAcceptSupportedExtensions() throws Exception { +113 JarAnalyzer instance = new JarAnalyzer(); +114 instance.initialize(); +115 instance.setEnabled(true); +116 String[] files = {"test.jar", "test.war"}; +117 for (String name : files) { +118 assertTrue(name, instance.accept(new File(name))); +119 } +120 } +121 +122 /** +123 * Test of getName method, of class JarAnalyzer. +124 */ +125 @Test +126 public void testGetName() { +127 JarAnalyzer instance = new JarAnalyzer(); +128 String expResult = "Jar Analyzer"; +129 String result = instance.getName(); +130 assertEquals(expResult, result); +131 } +132 +133 @Test +134 public void testParseManifest() throws Exception { +135 File file = BaseTest.getResourceAsFile(this, "xalan-2.7.0.jar"); +136 Dependency result = new Dependency(file); +137 JarAnalyzer instance = new JarAnalyzer(); +138 List<JarAnalyzer.ClassNameInformation> cni = new ArrayList<JarAnalyzer.ClassNameInformation>(); +139 instance.parseManifest(result, cni); +140 +141 assertTrue(result.getVersionEvidence().getEvidence("manifest: org/apache/xalan/").size() > 0); +142 } +143 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html index eb035d832..1a4f76d87 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html @@ -26,126 +26,211 @@ 18 package org.owasp.dependencycheck.analyzer; 19 20 import static org.hamcrest.CoreMatchers.is; -21 import static org.junit.Assert.assertThat; -22 import static org.junit.Assert.assertTrue; -23 -24 import java.io.File; -25 -26 import org.junit.After; -27 import org.junit.Assume; -28 import org.junit.Before; -29 import org.junit.Test; -30 import org.owasp.dependencycheck.BaseTest; -31 import org.owasp.dependencycheck.Engine; -32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -33 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.utils.Settings; -36 import org.slf4j.Logger; -37 import org.slf4j.LoggerFactory; -38 -39 /** -40 * Unit tests for {@link RubyBundleAuditAnalyzer}. -41 * -42 * @author Dale Visser -43 */ -44 public class RubyBundleAuditAnalyzerTest extends BaseTest { -45 -46 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); -47 -48 /** -49 * The analyzer to test. -50 */ -51 RubyBundleAuditAnalyzer analyzer; -52 -53 /** -54 * Correctly setup the analyzer for testing. -55 * -56 * @throws Exception thrown if there is a problem -57 */ -58 @Before -59 public void setUp() throws Exception { -60 Settings.initialize(); -61 analyzer = new RubyBundleAuditAnalyzer(); -62 analyzer.setFilesMatched(true); -63 } -64 -65 /** -66 * Cleanup the analyzer's temp files, etc. -67 * -68 * @throws Exception thrown if there is a problem -69 */ -70 @After -71 public void tearDown() throws Exception { -72 Settings.cleanup(); -73 analyzer.close(); -74 analyzer = null; -75 } -76 -77 /** -78 * Test Ruby Gemspec name. -79 */ -80 @Test -81 public void testGetName() { -82 assertThat(analyzer.getName(), is("Ruby Bundle Audit Analyzer")); -83 } -84 -85 /** -86 * Test Ruby Bundler Audit file support. -87 */ -88 @Test -89 public void testSupportsFiles() { -90 assertThat(analyzer.accept(new File("Gemfile.lock")), is(true)); -91 } -92 -93 /** -94 * Test Ruby BundlerAudit analysis. -95 * -96 * @throws AnalysisException is thrown when an exception occurs. +21 import static org.junit.Assert.assertEquals; +22 import static org.junit.Assert.assertThat; +23 import static org.junit.Assert.assertTrue; +24 +25 import java.io.File; +26 import java.util.Iterator; +27 import java.util.List; +28 import java.util.Set; +29 +30 import org.junit.After; +31 import org.junit.Assume; +32 import org.junit.Before; +33 import org.junit.Test; +34 import org.owasp.dependencycheck.BaseDBTestCase; +35 import org.owasp.dependencycheck.BaseTest; +36 import org.owasp.dependencycheck.Engine; +37 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +38 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +39 import org.owasp.dependencycheck.dependency.Dependency; +40 import org.owasp.dependencycheck.dependency.Evidence; +41 import org.owasp.dependencycheck.dependency.Identifier; +42 import org.owasp.dependencycheck.dependency.Vulnerability; +43 import org.owasp.dependencycheck.utils.Settings; +44 import org.slf4j.Logger; +45 import org.slf4j.LoggerFactory; +46 +47 /** +48 * Unit tests for {@link RubyBundleAuditAnalyzer}. +49 * +50 * @author Dale Visser +51 */ +52 public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { +53 +54 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); +55 +56 /** +57 * The analyzer to test. +58 */ +59 RubyBundleAuditAnalyzer analyzer; +60 +61 /** +62 * Correctly setup the analyzer for testing. +63 * +64 * @throws Exception thrown if there is a problem +65 */ +66 @Before +67 public void setUp() throws Exception { +68 super.setUp(); +69 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +70 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +71 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +72 analyzer = new RubyBundleAuditAnalyzer(); +73 analyzer.setFilesMatched(true); +74 } +75 +76 /** +77 * Cleanup the analyzer's temp files, etc. +78 * +79 * @throws Exception thrown if there is a problem +80 */ +81 @After +82 public void tearDown() throws Exception { +83 analyzer.close(); +84 analyzer = null; +85 } +86 +87 /** +88 * Test Ruby Gemspec name. +89 */ +90 @Test +91 public void testGetName() { +92 assertThat(analyzer.getName(), is("Ruby Bundle Audit Analyzer")); +93 } +94 +95 /** +96 * Test Ruby Bundler Audit file support. 97 */ 98 @Test -99 public void testAnalysis() throws AnalysisException, DatabaseException { -100 try { -101 analyzer.initialize(); +99 public void testSupportsFiles() { +100 assertThat(analyzer.accept(new File("Gemfile.lock")), is(true)); +101 } 102 -103 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, -104 "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock")); -105 final Engine engine = new Engine(); -106 analyzer.analyze(result, engine); -107 int size = engine.getDependencies().size(); -108 assertThat(size, is(1)); -109 -110 Dependency dependency = engine.getDependencies().get(0); -111 assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); -112 assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); -113 -114 } catch (Exception e) { -115 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); -116 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); -117 } -118 } +103 /** +104 * Test Ruby BundlerAudit analysis. +105 * +106 * @throws AnalysisException is thrown when an exception occurs. +107 */ +108 @Test +109 public void testAnalysis() throws AnalysisException, DatabaseException { +110 try { +111 analyzer.initialize(); +112 final String resource = "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock"; +113 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, resource)); +114 final Engine engine = new Engine(); +115 analyzer.analyze(result, engine); +116 int size = engine.getDependencies().size(); +117 +118 assertTrue(size >= 1); 119 -120 /** -121 * Test when Ruby bundle-audit is not available on the system. -122 * -123 * @throws AnalysisException is thrown when an exception occurs. -124 */ -125 @Test -126 public void testMissingBundleAudit() throws AnalysisException, DatabaseException { -127 //set a non-exist bundle-audit -128 Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit"); -129 try { -130 //initialize should fail. -131 analyzer.initialize(); -132 } catch (Exception e) { -133 //expected, so ignore. -134 } -135 finally { -136 assertThat(analyzer.isEnabled(), is(false)); -137 LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); -138 } -139 } -140 } +120 Dependency dependency = engine.getDependencies().get(0); +121 assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); +122 assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); +123 assertTrue(dependency.getFilePath().endsWith(resource)); +124 assertTrue(dependency.getFileName().equals("Gemfile.lock")); +125 } catch (Exception e) { +126 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\"."); +127 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); +128 } +129 } +130 +131 /** +132 * Test Ruby addCriticalityToVulnerability +133 */ +134 @Test +135 public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { +136 try { +137 analyzer.initialize(); +138 +139 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +140 "ruby/vulnerable/gems/sinatra/Gemfile.lock")); +141 final Engine engine = new Engine(); +142 analyzer.analyze(result, engine); +143 +144 Dependency dependency = engine.getDependencies().get(0); +145 Vulnerability vulnerability = dependency.getVulnerabilities().first(); +146 assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); +147 +148 } catch (Exception e) { +149 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); +150 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); +151 } +152 } +153 +154 /** +155 * Test when Ruby bundle-audit is not available on the system. +156 * +157 * @throws AnalysisException is thrown when an exception occurs. +158 */ +159 @Test +160 public void testMissingBundleAudit() throws AnalysisException, DatabaseException { +161 //set a non-exist bundle-audit +162 Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit"); +163 try { +164 //initialize should fail. +165 analyzer.initialize(); +166 } catch (Exception e) { +167 //expected, so ignore. +168 } finally { +169 assertThat(analyzer.isEnabled(), is(false)); +170 LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); +171 } +172 } +173 +174 /** +175 * Test Ruby dependencies and their paths. +176 * +177 * @throws AnalysisException is thrown when an exception occurs. +178 */ +179 @Test +180 public void testDependenciesPath() throws AnalysisException, DatabaseException { +181 final Engine engine = new Engine(); +182 engine.scan(BaseTest.getResourceAsFile(this, +183 "ruby/vulnerable/gems/rails-4.1.15/")); +184 try { +185 engine.analyzeDependencies(); +186 } catch (NullPointerException ex) { +187 LOGGER.error("NPE", ex); +188 throw ex; +189 } +190 List<Dependency> dependencies = engine.getDependencies(); +191 LOGGER.info(dependencies.size() + " dependencies found."); +192 Iterator<Dependency> dIterator = dependencies.iterator(); +193 while (dIterator.hasNext()) { +194 Dependency dept = dIterator.next(); +195 LOGGER.info("dept path: " + dept.getActualFilePath()); +196 +197 Set<Identifier> identifiers = dept.getIdentifiers(); +198 Iterator<Identifier> idIterator = identifiers.iterator(); +199 while (idIterator.hasNext()) { +200 Identifier id = idIterator.next(); +201 LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); +202 } +203 +204 Set<Evidence> prodEv = dept.getProductEvidence().getEvidence(); +205 Iterator<Evidence> it = prodEv.iterator(); +206 while (it.hasNext()) { +207 Evidence e = it.next(); +208 LOGGER.info(" prod: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +209 } +210 Set<Evidence> versionEv = dept.getVersionEvidence().getEvidence(); +211 Iterator<Evidence> vIt = versionEv.iterator(); +212 while (vIt.hasNext()) { +213 Evidence e = vIt.next(); +214 LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +215 } +216 +217 Set<Evidence> vendorEv = dept.getVendorEvidence().getEvidence(); +218 Iterator<Evidence> vendorIt = vendorEv.iterator(); +219 while (vendorIt.hasNext()) { +220 Evidence e = vendorIt.next(); +221 LOGGER.info(" vendor: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +222 } +223 } +224 } +225 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzerTest.html new file mode 100644 index 000000000..bfa703e57 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzerTest.html @@ -0,0 +1,119 @@ + + + +RubyBundlerAnalyzerTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +3    *
      +4    * Licensed under the Apache License, Version 2.0 (the "License");
      +5    * you may not use this file except in compliance with the License.
      +6    * You may obtain a copy of the License at
      +7    *
      +8    *     http://www.apache.org/licenses/LICENSE-2.0
      +9    *
      +10   * Unless required by applicable law or agreed to in writing, software
      +11   * distributed under the License is distributed on an "AS IS" BASIS,
      +12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      +13   * See the License for the specific language governing permissions and
      +14   * limitations under the License.
      +15   *
      +16   * Copyright (c) 2016 Bianca Jiang. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.analyzer;
      +19  
      +20  import org.junit.After;
      +21  import org.junit.Before;
      +22  import org.junit.Test;
      +23  import org.owasp.dependencycheck.BaseTest;
      +24  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      +25  import org.owasp.dependencycheck.dependency.Dependency;
      +26  
      +27  import java.io.File;
      +28  
      +29  import static org.hamcrest.CoreMatchers.containsString;
      +30  import static org.hamcrest.CoreMatchers.is;
      +31  import static org.junit.Assert.*;
      +32  
      +33  /**
      +34   * Unit tests for {@link RubyBundlerAnalyzer}.
      +35   *
      +36   * @author Bianca Jiang
      +37   */
      +38  public class RubyBundlerAnalyzerTest extends BaseTest {
      +39  
      +40      /**
      +41       * The analyzer to test.
      +42       */
      +43      RubyBundlerAnalyzer analyzer;
      +44  
      +45      /**
      +46       * Correctly setup the analyzer for testing.
      +47       *
      +48       * @throws Exception thrown if there is a problem
      +49       */
      +50      @Before
      +51      public void setUp() throws Exception {
      +52          analyzer = new RubyBundlerAnalyzer();
      +53          analyzer.setFilesMatched(true);
      +54          analyzer.initialize();
      +55      }
      +56  
      +57      /**
      +58       * Cleanup the analyzer's temp files, etc.
      +59       *
      +60       * @throws Exception thrown if there is a problem
      +61       */
      +62      @After
      +63      public void tearDown() throws Exception {
      +64          analyzer.close();
      +65          analyzer = null;
      +66      }
      +67  
      +68      /**
      +69       * Test Analyzer name.
      +70       */
      +71      @Test
      +72      public void testGetName() {
      +73          assertThat(analyzer.getName(), is("Ruby Bundler Analyzer"));
      +74      }
      +75  
      +76      /**
      +77       * Test Ruby Gemspec file support.
      +78       */
      +79      @Test
      +80      public void testSupportsFiles() {
      +81          assertThat(analyzer.accept(new File("test.gemspec")), is(false));
      +82          assertThat(analyzer.accept(new File("specifications" + File.separator + "test.gemspec")), is(true));
      +83      }
      +84  
      +85      /**
      +86       * Test Ruby Bundler created gemspec analysis.
      +87       *
      +88       * @throws AnalysisException is thrown when an exception occurs.
      +89       */
      +90      @Test
      +91      public void testAnalyzeGemspec() throws AnalysisException {
      +92          final Dependency result = new Dependency(BaseTest.getResourceAsFile(this,
      +93                  "ruby/vulnerable/gems/rails-4.1.15/vendor/bundle/ruby/2.2.0/specifications/dalli-2.7.5.gemspec"));
      +94          analyzer.analyze(result, null);
      +95          
      +96          final String vendorString = result.getVendorEvidence().toString();
      +97          assertThat(vendorString, containsString("Peter M. Goldstein"));
      +98          assertThat(vendorString, containsString("Mike Perham"));
      +99          assertThat(vendorString, containsString("peter.m.goldstein@gmail.com"));
      +100         assertThat(vendorString, containsString("https://github.com/petergoldstein/dalli"));
      +101         assertThat(vendorString, containsString("MIT"));
      +102         assertThat(result.getProductEvidence().toString(), containsString("dalli"));
      +103         assertThat(result.getProductEvidence().toString(), containsString("High performance memcached client for Ruby"));
      +104         assertThat(result.getVersionEvidence().toString(), containsString("2.7.5"));
      +105     }
      +106 }
      +
      +
      + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.html index 91ecb8244..f94636973 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.html @@ -87,7 +87,7 @@ 79 @Test 80 public void testSupportsFiles() { 81 assertThat(analyzer.accept(new File("test.gemspec")), is(true)); -82 assertThat(analyzer.accept(new File("Rakefile")), is(true)); +82 // assertThat(analyzer.accept(new File("Rakefile")), is(true)); 83 } 84 85 /** @@ -108,7 +108,20 @@ 100 assertThat(result.getProductEvidence().toString(), containsString("rest-client")); 101 assertThat(result.getVersionEvidence().toString(), containsString("1.7.2")); 102 } -103 } +103 +104 /** +105 * Test Rakefile analysis. +106 * +107 * @throws AnalysisException is thrown when an exception occurs. +108 */ +109 //@Test TODO: place holder to test Rakefile support +110 public void testAnalyzeRakefile() throws AnalysisException { +111 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +112 "ruby/vulnerable/gems/rails-4.1.15/vendor/bundle/ruby/2.2.0/gems/pg-0.18.4/Rakefile")); +113 analyzer.analyze(result, null); +114 //TODO add verification +115 } +116 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html index 6423f2e67..e7d182061 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer @@ -83,6 +83,9 @@
    58. RubyBundleAuditAnalyzerTest +
    59. +
    60. + RubyBundlerAnalyzerTest
    61. RubyGemspecAnalyzerTest diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html index a4c69e44d..17f0644b3 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer @@ -149,6 +149,11 @@ RubyBundleAuditAnalyzerTest + + + + RubyBundlerAnalyzerTest + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-frame.html index aca06a0b1..5216723c3 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.central diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-summary.html index f1771eddd..e3ab70d80 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.central diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.html index 63d364f69..201047b30 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.html @@ -33,48 +33,49 @@ 25 import java.nio.charset.Charset; 26 27 import static org.junit.Assert.*; -28 -29 /** -30 * Created by colezlaw on 9/5/15. -31 */ -32 public class ComposerLockParserTest { -33 -34 private InputStream inputStream; -35 -36 @Before -37 public void setUp() { -38 inputStream = this.getClass().getClassLoader().getResourceAsStream("composer.lock"); -39 } -40 -41 @Test -42 public void testValidComposerLock() { -43 ComposerLockParser clp = new ComposerLockParser(inputStream); -44 clp.process(); -45 assertEquals(30, clp.getDependencies().size()); -46 assertTrue(clp.getDependencies().contains(new ComposerDependency("symfony", "translation", "2.7.3"))); -47 } -48 -49 @Test(expected = ComposerException.class) -50 public void testNotJSON() throws Exception { -51 String input = "NOT VALID JSON"; -52 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); -53 clp.process(); -54 } -55 -56 @Test(expected = ComposerException.class) -57 public void testNotComposer() throws Exception { -58 String input = "[\"ham\",\"eggs\"]"; -59 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); -60 clp.process(); -61 } -62 -63 @Test(expected = ComposerException.class) -64 public void testNotPackagesArray() throws Exception { -65 String input = "{\"packages\":\"eleventy\"}"; -66 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); -67 clp.process(); -68 } -69 } +28 import org.owasp.dependencycheck.BaseTest; +29 +30 /** +31 * Created by colezlaw on 9/5/15. +32 */ +33 public class ComposerLockParserTest extends BaseTest { +34 +35 private InputStream inputStream; +36 +37 @Before +38 public void setUp() { +39 inputStream = this.getClass().getClassLoader().getResourceAsStream("composer.lock"); +40 } +41 +42 @Test +43 public void testValidComposerLock() { +44 ComposerLockParser clp = new ComposerLockParser(inputStream); +45 clp.process(); +46 assertEquals(30, clp.getDependencies().size()); +47 assertTrue(clp.getDependencies().contains(new ComposerDependency("symfony", "translation", "2.7.3"))); +48 } +49 +50 @Test(expected = ComposerException.class) +51 public void testNotJSON() throws Exception { +52 String input = "NOT VALID JSON"; +53 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); +54 clp.process(); +55 } +56 +57 @Test(expected = ComposerException.class) +58 public void testNotComposer() throws Exception { +59 String input = "[\"ham\",\"eggs\"]"; +60 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); +61 clp.process(); +62 } +63 +64 @Test(expected = ComposerException.class) +65 public void testNotPackagesArray() throws Exception { +66 String input = "{\"packages\":\"eleventy\"}"; +67 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); +68 clp.process(); +69 } +70 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html index a5bdfad79..8ec65e425 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.composer diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html index a342338ae..3cdb060aa 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.composer diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/IndexEntryTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/IndexEntryTest.html index 5fdb42332..f5a0eef05 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/IndexEntryTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/IndexEntryTest.html @@ -27,29 +27,30 @@ 19 20 import org.junit.Assert; 21 import org.junit.Test; -22 -23 /** -24 * -25 * @author Jeremy Long -26 */ -27 public class IndexEntryTest { -28 -29 /** -30 * Test of setName method, of class IndexEntry. -31 * -32 * @throws Exception is thrown when an exception occurs. -33 */ -34 @Test -35 public void testSetName() throws Exception { -36 String name = "cpe:/a:apache:struts:1.1:rc2"; -37 -38 IndexEntry instance = new IndexEntry(); -39 instance.parseName(name); -40 -41 Assert.assertEquals("apache", instance.getVendor()); -42 Assert.assertEquals("struts", instance.getProduct()); -43 } -44 } +22 import org.owasp.dependencycheck.BaseTest; +23 +24 /** +25 * +26 * @author Jeremy Long +27 */ +28 public class IndexEntryTest extends BaseTest { +29 +30 /** +31 * Test of setName method, of class IndexEntry. +32 * +33 * @throws Exception is thrown when an exception occurs. +34 */ +35 @Test +36 public void testSetName() throws Exception { +37 String name = "cpe:/a:apache:struts:1.1:rc2"; +38 +39 IndexEntry instance = new IndexEntry(); +40 instance.parseName(name); +41 +42 Assert.assertEquals("apache", instance.getVendor()); +43 Assert.assertEquals("struts", instance.getProduct()); +44 } +45 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html index 1889ec728..1c5950b8a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html index 7b5882536..1b0e8fb81 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html index 07379915f..4ce949ccd 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html @@ -31,78 +31,60 @@ 23 import org.junit.Before; 24 import org.junit.BeforeClass; 25 import org.junit.Test; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class CweDBTest { -32 -33 public CweDBTest() { -34 } -35 -36 @BeforeClass -37 public static void setUpClass() throws Exception { -38 } -39 -40 @AfterClass -41 public static void tearDownClass() throws Exception { -42 } -43 -44 @Before -45 public void setUp() { -46 } -47 -48 @After -49 public void tearDown() { -50 } -51 -52 /** -53 * Method to serialize the CWE HashMap. This is not used in production; this is only used once during dev to create -54 * the serialized HashMap. -55 */ -56 // @Test -57 // public void testUpdate() throws Exception { -58 // SAXParserFactory factory = SAXParserFactory.newInstance(); -59 // SAXParser saxParser = factory.newSAXParser(); -60 // -61 // CweHandler handler = new CweHandler(); -62 // //File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath()); -63 // File file = new File(this.getClass().getClassLoader().getResource("cwec_v2.5.xml").getPath()); -64 // -65 // saxParser.parse(file, handler); -66 // System.out.println("Found " + handler.getCwe().size() + " cwe entries."); -67 // Map<String, String> cwe = handler.getCwe(); -68 //// FileOutputStream fout = new FileOutputStream("target/current.csv"); -69 //// //FileOutputStream fout = new FileOutputStream("target/new.csv"); -70 //// PrintWriter writer = new PrintWriter(fout); -71 //// for (Map.Entry<String, String> entry : cwe.entrySet()) { -72 //// writer.print('"'); -73 //// writer.print(entry.getKey()); -74 //// writer.print('"'); -75 //// writer.print(','); -76 //// writer.print('"'); -77 //// writer.print(entry.getValue()); -78 //// writer.println('"'); -79 //// } -80 //// writer.close(); -81 // -82 // FileOutputStream fout = new FileOutputStream("src/main/resources/data/cwe.hashmap.serialized"); -83 // ObjectOutputStream objOut = new ObjectOutputStream(fout); -84 // objOut.writeObject(cwe); -85 // objOut.close(); -86 // } -87 /** -88 * Test of getCweName method, of class CweDB. -89 */ -90 @Test -91 public void testGetCweName() { -92 String cweId = "CWE-16"; -93 String expResult = "Configuration"; -94 String result = CweDB.getCweName(cweId); -95 assertEquals(expResult, result); -96 } -97 } +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public class CweDBTest extends BaseTest { +33 +34 /** +35 * Method to serialize the CWE HashMap. This is not used in production; this is only used once during dev to create +36 * the serialized HashMap. +37 */ +38 // @Test +39 // public void testUpdate() throws Exception { +40 // SAXParserFactory factory = SAXParserFactory.newInstance(); +41 // SAXParser saxParser = factory.newSAXParser(); +42 // +43 // CweHandler handler = new CweHandler(); +44 // //File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath()); +45 // File file = new File(this.getClass().getClassLoader().getResource("cwec_v2.5.xml").getPath()); +46 // +47 // saxParser.parse(file, handler); +48 // System.out.println("Found " + handler.getCwe().size() + " cwe entries."); +49 // Map<String, String> cwe = handler.getCwe(); +50 //// FileOutputStream fout = new FileOutputStream("target/current.csv"); +51 //// //FileOutputStream fout = new FileOutputStream("target/new.csv"); +52 //// PrintWriter writer = new PrintWriter(fout); +53 //// for (Map.Entry<String, String> entry : cwe.entrySet()) { +54 //// writer.print('"'); +55 //// writer.print(entry.getKey()); +56 //// writer.print('"'); +57 //// writer.print(','); +58 //// writer.print('"'); +59 //// writer.print(entry.getValue()); +60 //// writer.println('"'); +61 //// } +62 //// writer.close(); +63 // +64 // FileOutputStream fout = new FileOutputStream("src/main/resources/data/cwe.hashmap.serialized"); +65 // ObjectOutputStream objOut = new ObjectOutputStream(fout); +66 // objOut.writeObject(cwe); +67 // objOut.close(); +68 // } +69 /** +70 * Test of getCweName method, of class CweDB. +71 */ +72 @Test +73 public void testGetCweName() { +74 String cweId = "CWE-16"; +75 String expResult = "Configuration"; +76 String result = CweDB.getCweName(cweId); +77 assertEquals(expResult, result); +78 } +79 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html index b8ac19665..d1e36a9e3 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html index 0a7c24db2..7abed78ca 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html index f7f01c877..72486401a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html @@ -51,89 +51,74 @@ 43 import org.junit.Before; 44 import org.junit.BeforeClass; 45 import org.junit.Test; -46 -47 /** -48 * -49 * @author Jeremy Long -50 */ -51 public class FieldAnalyzerTest { -52 -53 @BeforeClass -54 public static void setUpClass() throws Exception { -55 } +46 import org.owasp.dependencycheck.BaseTest; +47 +48 /** +49 * +50 * @author Jeremy Long +51 */ +52 public class FieldAnalyzerTest extends BaseTest { +53 +54 @Test +55 public void testAnalyzers() throws Exception { 56 -57 @AfterClass -58 public static void tearDownClass() throws Exception { -59 } -60 -61 @Before -62 public void setUp() { -63 } -64 -65 @After -66 public void tearDown() { -67 } -68 -69 @Test -70 public void testAnalyzers() throws Exception { -71 -72 Analyzer analyzer = new FieldAnalyzer(LuceneUtils.CURRENT_VERSION); -73 Directory index = new RAMDirectory(); -74 -75 String field1 = "product"; -76 String text1 = "springframework"; -77 -78 String field2 = "vendor"; -79 String text2 = "springsource"; -80 -81 createIndex(analyzer, index, field1, text1, field2, text2); -82 -83 //Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -84 String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)"; -85 -86 SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -87 SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -88 HashMap<String, Analyzer> map = new HashMap<String, Analyzer>(); -89 map.put(field1, searchAnalyzerProduct); -90 map.put(field2, searchAnalyzerVendor); -91 PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map); -92 QueryParser parser = new QueryParser(LuceneUtils.CURRENT_VERSION, field1, wrapper); -93 -94 Query q = parser.parse(querystr); -95 //System.out.println(q.toString()); -96 -97 int hitsPerPage = 10; -98 -99 IndexReader reader = DirectoryReader.open(index); -100 IndexSearcher searcher = new IndexSearcher(reader); -101 TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); -102 searcher.search(q, collector); -103 ScoreDoc[] hits = collector.topDocs().scoreDocs; -104 -105 assertEquals("Did not find 1 document?", 1, hits.length); +57 Analyzer analyzer = new FieldAnalyzer(LuceneUtils.CURRENT_VERSION); +58 Directory index = new RAMDirectory(); +59 +60 String field1 = "product"; +61 String text1 = "springframework"; +62 +63 String field2 = "vendor"; +64 String text2 = "springsource"; +65 +66 createIndex(analyzer, index, field1, text1, field2, text2); +67 +68 //Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +69 String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)"; +70 +71 SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +72 SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +73 HashMap<String, Analyzer> map = new HashMap<String, Analyzer>(); +74 map.put(field1, searchAnalyzerProduct); +75 map.put(field2, searchAnalyzerVendor); +76 PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map); +77 QueryParser parser = new QueryParser(LuceneUtils.CURRENT_VERSION, field1, wrapper); +78 +79 Query q = parser.parse(querystr); +80 //System.out.println(q.toString()); +81 +82 int hitsPerPage = 10; +83 +84 IndexReader reader = DirectoryReader.open(index); +85 IndexSearcher searcher = new IndexSearcher(reader); +86 TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); +87 searcher.search(q, collector); +88 ScoreDoc[] hits = collector.topDocs().scoreDocs; +89 +90 assertEquals("Did not find 1 document?", 1, hits.length); +91 +92 searchAnalyzerProduct.clear(); //ensure we don't have anything left over from the previous search. +93 searchAnalyzerVendor.clear(); +94 querystr = "product:(Apache Struts) vendor:(Apache)"; +95 Query q2 = parser.parse(querystr); +96 //System.out.println(q2.toString()); +97 assertFalse("second parsing contains previousWord from the TokenPairConcatenatingFilter", q2.toString().contains("core")); +98 } +99 +100 private void createIndex(Analyzer analyzer, Directory index, String field1, String text1, String field2, String text2) throws IOException { +101 IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); +102 IndexWriter w = new IndexWriter(index, config); +103 addDoc(w, field1, text1, field2, text2); +104 w.close(); +105 } 106 -107 searchAnalyzerProduct.clear(); //ensure we don't have anything left over from the previous search. -108 searchAnalyzerVendor.clear(); -109 querystr = "product:(Apache Struts) vendor:(Apache)"; -110 Query q2 = parser.parse(querystr); -111 //System.out.println(q2.toString()); -112 assertFalse("second parsing contains previousWord from the TokenPairConcatenatingFilter", q2.toString().contains("core")); -113 } -114 -115 private void createIndex(Analyzer analyzer, Directory index, String field1, String text1, String field2, String text2) throws IOException { -116 IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); -117 IndexWriter w = new IndexWriter(index, config); -118 addDoc(w, field1, text1, field2, text2); -119 w.close(); -120 } -121 -122 private static void addDoc(IndexWriter w, String field1, String text1, String field2, String text2) throws IOException { -123 Document doc = new Document(); -124 doc.add(new TextField(field1, text1, Field.Store.YES)); -125 doc.add(new TextField(field2, text2, Field.Store.YES)); -126 w.addDocument(doc); -127 } -128 } +107 private static void addDoc(IndexWriter w, String field1, String text1, String field2, String text2) throws IOException { +108 Document doc = new Document(); +109 doc.add(new TextField(field1, text1, Field.Store.YES)); +110 doc.add(new TextField(field2, text2, Field.Store.YES)); +111 w.addDocument(doc); +112 } +113 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html index 068f8fbe4..5ebc9bc1e 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html @@ -31,74 +31,59 @@ 23 import org.junit.Before; 24 import org.junit.BeforeClass; 25 import org.junit.Test; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class LuceneUtilsTest { -32 -33 @BeforeClass -34 public static void setUpClass() throws Exception { -35 } -36 -37 @AfterClass -38 public static void tearDownClass() throws Exception { -39 } -40 -41 @Before -42 public void setUp() { -43 } -44 -45 @After -46 public void tearDown() { -47 } -48 -49 /** -50 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. -51 */ -52 @Test -53 public void testAppendEscapedLuceneQuery() { -54 StringBuilder buf = new StringBuilder(); -55 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; -56 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; -57 LuceneUtils.appendEscapedLuceneQuery(buf, text); -58 assertEquals(expResult, buf.toString()); -59 } -60 -61 /** -62 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. -63 */ -64 @Test -65 public void testAppendEscapedLuceneQuery_null() { -66 StringBuilder buf = new StringBuilder(); -67 CharSequence text = null; -68 LuceneUtils.appendEscapedLuceneQuery(buf, text); -69 assertEquals(0, buf.length()); -70 } -71 -72 /** -73 * Test of escapeLuceneQuery method, of class LuceneUtils. -74 */ -75 @Test -76 public void testEscapeLuceneQuery() { -77 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; -78 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; -79 String result = LuceneUtils.escapeLuceneQuery(text); -80 assertEquals(expResult, result); -81 } -82 -83 /** -84 * Test of escapeLuceneQuery method, of class LuceneUtils. -85 */ -86 @Test -87 public void testEscapeLuceneQuery_null() { -88 CharSequence text = null; -89 String expResult = null; -90 String result = LuceneUtils.escapeLuceneQuery(text); -91 assertEquals(expResult, result); -92 } -93 } +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public class LuceneUtilsTest extends BaseTest { +33 +34 /** +35 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. +36 */ +37 @Test +38 public void testAppendEscapedLuceneQuery() { +39 StringBuilder buf = new StringBuilder(); +40 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; +41 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; +42 LuceneUtils.appendEscapedLuceneQuery(buf, text); +43 assertEquals(expResult, buf.toString()); +44 } +45 +46 /** +47 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. +48 */ +49 @Test +50 public void testAppendEscapedLuceneQuery_null() { +51 StringBuilder buf = new StringBuilder(); +52 CharSequence text = null; +53 LuceneUtils.appendEscapedLuceneQuery(buf, text); +54 assertEquals(0, buf.length()); +55 } +56 +57 /** +58 * Test of escapeLuceneQuery method, of class LuceneUtils. +59 */ +60 @Test +61 public void testEscapeLuceneQuery() { +62 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; +63 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; +64 String result = LuceneUtils.escapeLuceneQuery(text); +65 assertEquals(expResult, result); +66 } +67 +68 /** +69 * Test of escapeLuceneQuery method, of class LuceneUtils. +70 */ +71 @Test +72 public void testEscapeLuceneQuery_null() { +73 CharSequence text = null; +74 String expResult = null; +75 String result = LuceneUtils.escapeLuceneQuery(text); +76 assertEquals(expResult, result); +77 } +78 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html index fe7104be7..f70d8c3ff 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html @@ -47,54 +47,46 @@ 39 */ 40 public class TokenPairConcatenatingFilterTest extends BaseTokenStreamTestCase { 41 -42 @BeforeClass -43 public static void setUpClass() { -44 } -45 -46 @AfterClass -47 public static void tearDownClass() { -48 } -49 -50 @Override -51 @Before -52 public void setUp() throws Exception { -53 super.setUp(); -54 } -55 -56 @Override -57 @After -58 public void tearDown() throws Exception { -59 super.tearDown(); -60 } -61 -62 /** -63 * test some examples -64 */ -65 public void testExamples() throws IOException { -66 Tokenizer wsTokenizer = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); -67 TokenStream filter = new TokenPairConcatenatingFilter(wsTokenizer); -68 assertTokenStreamContents(filter, -69 new String[]{"one", "onetwo", "two", "twothree", "three"}); -70 } +42 @Override +43 @Before +44 public void setUp() throws Exception { +45 super.setUp(); +46 } +47 +48 @Override +49 @After +50 public void tearDown() throws Exception { +51 super.tearDown(); +52 } +53 +54 /** +55 * test some examples +56 */ +57 public void testExamples() throws IOException { +58 Tokenizer wsTokenizer = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); +59 TokenStream filter = new TokenPairConcatenatingFilter(wsTokenizer); +60 assertTokenStreamContents(filter, +61 new String[]{"one", "onetwo", "two", "twothree", "three"}); +62 } +63 +64 /** +65 * Test of clear method, of class TokenPairConcatenatingFilter. +66 * +67 * @throws java.io.IOException +68 */ +69 @Test +70 public void testClear() throws IOException { 71 -72 /** -73 * Test of clear method, of class TokenPairConcatenatingFilter. -74 * -75 * @throws java.io.IOException -76 */ -77 @Test -78 public void testClear() throws IOException { -79 -80 TokenStream ts = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); -81 TokenPairConcatenatingFilter filter = new TokenPairConcatenatingFilter(ts); -82 assertTokenStreamContents(filter, new String[]{"one", "onetwo", "two", "twothree", "three"}); -83 -84 assertNotNull(filter.getPreviousWord()); -85 filter.clear(); -86 assertNull(filter.getPreviousWord()); -87 assertTrue(filter.getWords().isEmpty()); -88 } -89 } +72 TokenStream ts = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); +73 TokenPairConcatenatingFilter filter = new TokenPairConcatenatingFilter(ts); +74 assertTokenStreamContents(filter, new String[]{"one", "onetwo", "two", "twothree", "three"}); +75 +76 assertNotNull(filter.getPreviousWord()); +77 filter.clear(); +78 assertNull(filter.getPreviousWord()); +79 assertTrue(filter.getWords().isEmpty()); +80 } +81 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html index 08d5187eb..1b199f1ff 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html index 171e48ce7..b20f5b9d4 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html index 85e5ce40a..a973a5c32 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html index 691d02a59..8ec76a390 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html index 8bda52742..ed3214030 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html index 98d3f6437..588ad768e 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.html index 579d7ed3c..e994487c5 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.html @@ -32,162 +32,183 @@ 24 import java.util.Map.Entry; 25 import java.util.Set; 26 import org.junit.Assert; -27 import static org.junit.Assert.assertTrue; -28 import org.junit.Test; -29 import org.owasp.dependencycheck.dependency.Vulnerability; -30 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -31 import org.owasp.dependencycheck.utils.DependencyVersion; -32 -33 /** -34 * -35 * @author Jeremy Long -36 */ -37 public class CveDBIntegrationTest extends BaseDBTestCase { -38 -39 /** -40 * Pretty useless tests of open, commit, and close methods, of class CveDB. -41 */ -42 @Test -43 public void testOpen() throws Exception { -44 CveDB instance = null; -45 try { -46 instance = new CveDB(); -47 instance.open(); -48 instance.commit(); -49 } finally { -50 if (instance != null) { -51 instance.close(); -52 } -53 } -54 } -55 -56 /** -57 * Test of getCPEs method, of class CveDB. -58 */ -59 @Test -60 public void testGetCPEs() throws Exception { -61 CveDB instance = null; -62 try { -63 instance = new CveDB(); -64 String vendor = "apache"; -65 String product = "struts"; -66 instance.open(); -67 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); -68 assertTrue(result.size() > 5); -69 } finally { -70 if (instance != null) { -71 instance.close(); -72 } -73 } -74 } -75 -76 /** -77 * Test of getVulnerabilities method, of class CveDB. -78 */ -79 @Test -80 public void testGetVulnerabilities() throws Exception { -81 String cpeStr = "cpe:/a:apache:struts:2.1.2"; -82 CveDB instance = null; -83 List<Vulnerability> results; +27 +28 import static org.junit.Assert.assertEquals; +29 import static org.junit.Assert.assertTrue; +30 import org.junit.Test; +31 import org.owasp.dependencycheck.dependency.Vulnerability; +32 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +33 import org.owasp.dependencycheck.utils.DependencyVersion; +34 +35 /** +36 * +37 * @author Jeremy Long +38 */ +39 public class CveDBIntegrationTest extends BaseDBTestCase { +40 +41 /** +42 * Pretty useless tests of open, commit, and close methods, of class CveDB. +43 */ +44 @Test +45 public void testOpen() throws Exception { +46 CveDB instance = null; +47 try { +48 instance = new CveDB(); +49 instance.open(); +50 instance.commit(); +51 } finally { +52 if (instance != null) { +53 instance.close(); +54 } +55 } +56 } +57 +58 /** +59 * Test of getCPEs method, of class CveDB. +60 */ +61 @Test +62 public void testGetCPEs() throws Exception { +63 CveDB instance = null; +64 try { +65 instance = new CveDB(); +66 String vendor = "apache"; +67 String product = "struts"; +68 instance.open(); +69 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); +70 assertTrue(result.size() > 5); +71 } finally { +72 if (instance != null) { +73 instance.close(); +74 } +75 } +76 } +77 +78 /** +79 * Test of getVulnerability method, of class CveDB. +80 */ +81 @Test +82 public void testgetVulnerability() throws Exception { +83 CveDB instance = null; 84 try { 85 instance = new CveDB(); 86 instance.open(); -87 results = instance.getVulnerabilities(cpeStr); -88 assertTrue(results.size() > 5); -89 cpeStr = "cpe:/a:jruby:jruby:1.6.3"; -90 results = instance.getVulnerabilities(cpeStr); -91 assertTrue(results.size() > 1); -92 -93 boolean found = false; -94 String expected = "CVE-2011-4838"; -95 for (Vulnerability v : results) { -96 if (expected.equals(v.getName())) { -97 found = true; -98 break; -99 } -100 } -101 assertTrue("Expected " + expected + ", but was not identified", found); -102 -103 found = false; -104 expected = "CVE-2012-5370"; -105 for (Vulnerability v : results) { -106 if (expected.equals(v.getName())) { -107 found = true; -108 break; -109 } -110 } -111 assertTrue("Expected " + expected + ", but was not identified", found); -112 -113 } finally { -114 if (instance != null) { -115 instance.close(); -116 } -117 } -118 } -119 -120 /** -121 * Test of getMatchingSoftware method, of class CveDB. -122 */ -123 @Test -124 public void testGetMatchingSoftware() throws Exception { -125 CveDB instance = null; -126 Map<String, Boolean> versions = new HashMap<String, Boolean>(); -127 DependencyVersion identifiedVersion = new DependencyVersion("1.0.1o"); -128 versions.put("cpe:/a:openssl:openssl:1.0.1e", Boolean.FALSE); -129 try { -130 instance = new CveDB(); -131 Entry<String, Boolean> results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); -132 Assert.assertNull(results); -133 versions.put("cpe:/a:openssl:openssl:1.0.1p", Boolean.FALSE); -134 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); -135 Assert.assertNull(results); -136 -137 versions.put("cpe:/a:openssl:openssl:1.0.1q", Boolean.TRUE); -138 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); -139 Assert.assertNotNull(results); -140 Assert.assertEquals("cpe:/a:openssl:openssl:1.0.1q", results.getKey()); -141 -142 versions.clear(); -143 -144 versions.put("cpe:/a:springsource:spring_framework:3.2.5", Boolean.FALSE); -145 versions.put("cpe:/a:springsource:spring_framework:3.2.6", Boolean.FALSE); -146 versions.put("cpe:/a:springsource:spring_framework:3.2.7", Boolean.TRUE); -147 -148 versions.put("cpe:/a:springsource:spring_framework:4.0.1", Boolean.TRUE); -149 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m1", Boolean.FALSE); -150 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m2", Boolean.FALSE); -151 versions.put("cpe:/a:springsource:spring_framework:4.0.0:rc1", Boolean.FALSE); -152 -153 identifiedVersion = new DependencyVersion("3.2.2"); -154 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -155 Assert.assertEquals("cpe:/a:springsource:spring_framework:3.2.7", results.getKey()); -156 Assert.assertTrue(results.getValue()); -157 identifiedVersion = new DependencyVersion("3.2.12"); -158 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -159 Assert.assertNull(results); -160 -161 identifiedVersion = new DependencyVersion("4.0.0"); -162 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -163 Assert.assertEquals("cpe:/a:springsource:spring_framework:4.0.1", results.getKey()); -164 Assert.assertTrue(results.getValue()); -165 identifiedVersion = new DependencyVersion("4.1.0"); -166 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -167 Assert.assertNull(results); +87 Vulnerability result = instance.getVulnerability("CVE-2014-0094"); +88 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()); +89 +90 } finally { +91 if (instance != null) { +92 instance.close(); +93 } +94 } +95 } +96 +97 /** +98 * Test of getVulnerabilities method, of class CveDB. +99 */ +100 @Test +101 public void testGetVulnerabilities() throws Exception { +102 String cpeStr = "cpe:/a:apache:struts:2.1.2"; +103 CveDB instance = null; +104 List<Vulnerability> results; +105 try { +106 instance = new CveDB(); +107 instance.open(); +108 results = instance.getVulnerabilities(cpeStr); +109 assertTrue(results.size() > 5); +110 cpeStr = "cpe:/a:jruby:jruby:1.6.3"; +111 results = instance.getVulnerabilities(cpeStr); +112 assertTrue(results.size() > 1); +113 +114 boolean found = false; +115 String expected = "CVE-2011-4838"; +116 for (Vulnerability v : results) { +117 if (expected.equals(v.getName())) { +118 found = true; +119 break; +120 } +121 } +122 assertTrue("Expected " + expected + ", but was not identified", found); +123 +124 found = false; +125 expected = "CVE-2012-5370"; +126 for (Vulnerability v : results) { +127 if (expected.equals(v.getName())) { +128 found = true; +129 break; +130 } +131 } +132 assertTrue("Expected " + expected + ", but was not identified", found); +133 +134 } finally { +135 if (instance != null) { +136 instance.close(); +137 } +138 } +139 } +140 +141 /** +142 * Test of getMatchingSoftware method, of class CveDB. +143 */ +144 @Test +145 public void testGetMatchingSoftware() throws Exception { +146 CveDB instance = null; +147 Map<String, Boolean> versions = new HashMap<String, Boolean>(); +148 DependencyVersion identifiedVersion = new DependencyVersion("1.0.1o"); +149 versions.put("cpe:/a:openssl:openssl:1.0.1e", Boolean.FALSE); +150 try { +151 instance = new CveDB(); +152 Entry<String, Boolean> results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); +153 Assert.assertNull(results); +154 versions.put("cpe:/a:openssl:openssl:1.0.1p", Boolean.FALSE); +155 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); +156 Assert.assertNull(results); +157 +158 versions.put("cpe:/a:openssl:openssl:1.0.1q", Boolean.TRUE); +159 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); +160 Assert.assertNotNull(results); +161 Assert.assertEquals("cpe:/a:openssl:openssl:1.0.1q", results.getKey()); +162 +163 versions.clear(); +164 +165 versions.put("cpe:/a:springsource:spring_framework:3.2.5", Boolean.FALSE); +166 versions.put("cpe:/a:springsource:spring_framework:3.2.6", Boolean.FALSE); +167 versions.put("cpe:/a:springsource:spring_framework:3.2.7", Boolean.TRUE); 168 -169 versions.clear(); -170 -171 versions.put("cpe:/a:jruby:jruby:-", Boolean.FALSE); -172 identifiedVersion = new DependencyVersion("1.6.3"); -173 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -174 Assert.assertNotNull(results); -175 } finally { -176 if (instance != null) { -177 instance.close(); -178 } -179 } -180 } +169 versions.put("cpe:/a:springsource:spring_framework:4.0.1", Boolean.TRUE); +170 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m1", Boolean.FALSE); +171 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m2", Boolean.FALSE); +172 versions.put("cpe:/a:springsource:spring_framework:4.0.0:rc1", Boolean.FALSE); +173 +174 identifiedVersion = new DependencyVersion("3.2.2"); +175 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +176 Assert.assertEquals("cpe:/a:springsource:spring_framework:3.2.7", results.getKey()); +177 Assert.assertTrue(results.getValue()); +178 identifiedVersion = new DependencyVersion("3.2.12"); +179 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +180 Assert.assertNull(results); 181 -182 } +182 identifiedVersion = new DependencyVersion("4.0.0"); +183 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +184 Assert.assertEquals("cpe:/a:springsource:spring_framework:4.0.1", results.getKey()); +185 Assert.assertTrue(results.getValue()); +186 identifiedVersion = new DependencyVersion("4.1.0"); +187 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +188 Assert.assertNull(results); +189 +190 versions.clear(); +191 +192 versions.put("cpe:/a:jruby:jruby:-", Boolean.FALSE); +193 identifiedVersion = new DependencyVersion("1.6.3"); +194 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +195 Assert.assertNotNull(results); +196 } finally { +197 if (instance != null) { +198 instance.close(); +199 } +200 } +201 } +202 +203 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html index 1dabd5f74..e861d3cbf 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html @@ -33,88 +33,71 @@ 25 import org.junit.Before; 26 import org.junit.BeforeClass; 27 import org.junit.Test; -28 import org.owasp.dependencycheck.dependency.Vulnerability; -29 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -30 import org.owasp.dependencycheck.utils.Settings; -31 -32 /** -33 * -34 * @author Jeremy Long -35 */ -36 public class CveDBMySQLTest { -37 -38 @BeforeClass -39 public static void setUpClass() { -40 Settings.initialize(); -41 } -42 -43 @AfterClass -44 public static void tearDownClass() { -45 Settings.cleanup(); -46 } -47 -48 @Before -49 public void setUp() throws Exception { -50 } -51 -52 @After -53 public void tearDown() throws Exception { -54 } -55 -56 /** -57 * Pretty useless tests of open, commit, and close methods, of class CveDB. -58 */ -59 @Test -60 public void testOpen() throws DatabaseException { -61 try { -62 CveDB instance = new CveDB(); +28 import org.owasp.dependencycheck.BaseTest; +29 import org.owasp.dependencycheck.dependency.Vulnerability; +30 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +31 import org.owasp.dependencycheck.utils.Settings; +32 +33 /** +34 * +35 * @author Jeremy Long +36 */ +37 public class CveDBMySQLTest extends BaseTest { +38 +39 /** +40 * Pretty useless tests of open, commit, and close methods, of class CveDB. +41 */ +42 @Test +43 public void testOpen() throws DatabaseException { +44 try { +45 CveDB instance = new CveDB(); +46 instance.open(); +47 instance.close(); +48 } catch (DatabaseException ex) { +49 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"); +50 throw ex; +51 } +52 } +53 +54 /** +55 * Test of getCPEs method, of class CveDB. +56 */ +57 @Test +58 public void testGetCPEs() throws Exception { +59 CveDB instance = new CveDB(); +60 try { +61 String vendor = "apache"; +62 String product = "struts"; 63 instance.open(); -64 instance.close(); -65 } catch (DatabaseException ex) { -66 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"); -67 throw ex; -68 } -69 } -70 -71 /** -72 * Test of getCPEs method, of class CveDB. -73 */ -74 @Test -75 public void testGetCPEs() throws Exception { -76 CveDB instance = new CveDB(); -77 try { -78 String vendor = "apache"; -79 String product = "struts"; -80 instance.open(); -81 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); -82 assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); -83 } catch (Exception ex) { -84 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); -85 throw ex; -86 } finally { -87 instance.close(); -88 } -89 } -90 -91 /** -92 * Test of getVulnerabilities method, of class CveDB. -93 */ -94 @Test -95 public void testGetVulnerabilities() throws Exception { -96 String cpeStr = "cpe:/a:apache:struts:2.1.2"; -97 CveDB instance = new CveDB(); -98 try { -99 instance.open(); -100 List<Vulnerability> result = instance.getVulnerabilities(cpeStr); -101 assertTrue(result.size() > 5); -102 } catch (Exception ex) { -103 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); -104 throw ex; -105 } finally { -106 instance.close(); -107 } -108 } -109 } +64 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); +65 assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); +66 } catch (Exception ex) { +67 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); +68 throw ex; +69 } finally { +70 instance.close(); +71 } +72 } +73 +74 /** +75 * Test of getVulnerabilities method, of class CveDB. +76 */ +77 @Test +78 public void testGetVulnerabilities() throws Exception { +79 String cpeStr = "cpe:/a:apache:struts:2.1.2"; +80 CveDB instance = new CveDB(); +81 try { +82 instance.open(); +83 List<Vulnerability> result = instance.getVulnerabilities(cpeStr); +84 assertTrue(result.size() > 5); +85 } catch (Exception ex) { +86 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); +87 throw ex; +88 } finally { +89 instance.close(); +90 } +91 } +92 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html index 53a1a956b..ddf2c22d1 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html @@ -41,127 +41,109 @@ 33 * 34 * @author Jeremy Long 35 */ -36 public class DriverLoaderTest { +36 public class DriverLoaderTest extends BaseTest { 37 -38 public DriverLoaderTest() { -39 } -40 -41 @BeforeClass -42 public static void setUpClass() { -43 } -44 -45 @AfterClass -46 public static void tearDownClass() { -47 } -48 -49 @Before -50 public void setUp() { -51 } -52 -53 @After -54 public void tearDown() { -55 } -56 -57 /** -58 * Test of load method, of class DriverLoader. -59 */ -60 @Test -61 public void testLoad_String() throws Exception { -62 String className = "org.h2.Driver"; -63 Driver d = null; -64 try { -65 d = DriverLoader.load(className); -66 } finally { -67 if (d != null) { -68 DriverManager.deregisterDriver(d); -69 } -70 } -71 } -72 -73 /** -74 * Test of load method, of class DriverLoader; expecting an exception due to a bad driver class name. -75 */ -76 @Test(expected = DriverLoadException.class) -77 public void testLoad_String_ex() throws Exception { -78 String className = "bad.Driver"; -79 Driver d = DriverLoader.load(className); -80 } -81 -82 /** -83 * Test of load method, of class DriverLoader. -84 */ -85 @Test -86 public void testLoad_String_String() throws Exception { -87 String className = "com.mysql.jdbc.Driver"; -88 //we know this is in target/test-classes -89 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -90 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -91 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); -92 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); -93 -94 Driver d = null; -95 try { -96 d = DriverLoader.load(className, driver.getAbsolutePath()); -97 d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck"); -98 assertNotNull(d); -99 } finally { -100 if (d != null) { -101 DriverManager.deregisterDriver(d); -102 } -103 } -104 } -105 -106 /** -107 * Test of load method, of class DriverLoader. -108 */ -109 @Test -110 public void testLoad_String_String_multiple_paths() throws Exception { -111 final String className = "com.mysql.jdbc.Driver"; -112 //we know this is in target/test-classes -113 //final File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -114 final File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -115 final File dir1 = new File(testClassPath, "../../src/test/"); -116 final File dir2 = new File(testClassPath, "../../src/test/resources/"); -117 final String paths = String.format("%s" + File.pathSeparator + "%s", dir1.getAbsolutePath(), dir2.getAbsolutePath()); -118 -119 Driver d = null; -120 try { -121 d = DriverLoader.load(className, paths); -122 } finally { -123 if (d != null) { -124 DriverManager.deregisterDriver(d); -125 } -126 } -127 } -128 -129 /** -130 * Test of load method, of class DriverLoader with an incorrect class name. -131 */ -132 @Test(expected = DriverLoadException.class) -133 public void testLoad_String_String_badClassName() throws Exception { -134 String className = "com.mybad.jdbc.Driver"; -135 //we know this is in target/test-classes -136 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -137 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -138 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); -139 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); -140 -141 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); -142 } -143 -144 /** -145 * Test of load method, of class DriverLoader with an incorrect class path. -146 */ -147 @Test(expected = DriverLoadException.class) -148 public void testLoad_String_String_badPath() throws Exception { -149 String className = "com.mysql.jdbc.Driver"; -150 //we know this is in target/test-classes -151 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -152 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -153 File driver = new File(testClassPath, "../../src/test/bad/mysql-connector-java-5.1.27-bin.jar"); -154 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); -155 } -156 } +38 /** +39 * Test of load method, of class DriverLoader. +40 */ +41 @Test +42 public void testLoad_String() throws Exception { +43 String className = "org.h2.Driver"; +44 Driver d = null; +45 try { +46 d = DriverLoader.load(className); +47 } finally { +48 if (d != null) { +49 DriverManager.deregisterDriver(d); +50 } +51 } +52 } +53 +54 /** +55 * Test of load method, of class DriverLoader; expecting an exception due to +56 * a bad driver class name. +57 */ +58 @Test(expected = DriverLoadException.class) +59 public void testLoad_String_ex() throws Exception { +60 String className = "bad.Driver"; +61 Driver d = DriverLoader.load(className); +62 } +63 +64 /** +65 * Test of load method, of class DriverLoader. +66 */ +67 @Test +68 public void testLoad_String_String() throws Exception { +69 String className = "com.mysql.jdbc.Driver"; +70 //we know this is in target/test-classes +71 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +72 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +73 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); +74 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); +75 +76 Driver d = null; +77 try { +78 d = DriverLoader.load(className, driver.getAbsolutePath()); +79 d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck"); +80 assertNotNull(d); +81 } finally { +82 if (d != null) { +83 DriverManager.deregisterDriver(d); +84 } +85 } +86 } +87 +88 /** +89 * Test of load method, of class DriverLoader. +90 */ +91 @Test +92 public void testLoad_String_String_multiple_paths() throws Exception { +93 final String className = "com.mysql.jdbc.Driver"; +94 //we know this is in target/test-classes +95 //final File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +96 final File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +97 final File dir1 = new File(testClassPath, "../../src/test/"); +98 final File dir2 = new File(testClassPath, "../../src/test/resources/"); +99 final String paths = String.format("%s" + File.pathSeparator + "%s", dir1.getAbsolutePath(), dir2.getAbsolutePath()); +100 +101 Driver d = null; +102 try { +103 d = DriverLoader.load(className, paths); +104 } finally { +105 if (d != null) { +106 DriverManager.deregisterDriver(d); +107 } +108 } +109 } +110 +111 /** +112 * Test of load method, of class DriverLoader with an incorrect class name. +113 */ +114 @Test(expected = DriverLoadException.class) +115 public void testLoad_String_String_badClassName() throws Exception { +116 String className = "com.mybad.jdbc.Driver"; +117 //we know this is in target/test-classes +118 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +119 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +120 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); +121 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); +122 +123 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); +124 } +125 +126 /** +127 * Test of load method, of class DriverLoader with an incorrect class path. +128 */ +129 @Test(expected = DriverLoadException.class) +130 public void testLoad_String_String_badPath() throws Exception { +131 String className = "com.mysql.jdbc.Driver"; +132 //we know this is in target/test-classes +133 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +134 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +135 File driver = new File(testClassPath, "../../src/test/bad/mysql-connector-java-5.1.27-bin.jar"); +136 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); +137 } +138 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html index 47a6efb0e..9eb69be17 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html index 2ebd22021..f0f4dc42b 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html index 3a36bbbdb..8881857a7 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html @@ -44,41 +44,22 @@ 36 * 37 * @author Jeremy Long 38 */ -39 public class NvdCve_1_2_HandlerTest { +39 public class NvdCve_1_2_HandlerTest extends BaseTest { 40 -41 public NvdCve_1_2_HandlerTest() { -42 } -43 -44 @BeforeClass -45 public static void setUpClass() throws Exception { -46 } -47 -48 @AfterClass -49 public static void tearDownClass() throws Exception { -50 } -51 -52 @Before -53 public void setUp() { -54 } -55 -56 @After -57 public void tearDown() { -58 } -59 -60 @Test -61 public void testParse() throws Exception { -62 SAXParserFactory factory = SAXParserFactory.newInstance(); -63 SAXParser saxParser = factory.newSAXParser(); -64 -65 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2012.xml").getPath()); -66 File file = BaseTest.getResourceAsFile(this, "nvdcve-2012.xml"); -67 -68 NvdCve12Handler instance = new NvdCve12Handler(); -69 saxParser.parse(file, instance); -70 Map<String, List<VulnerableSoftware>> results = instance.getVulnerabilities(); -71 assertTrue("No vulnerable software identified with a previous version in 2012 CVE 1.2?", !results.isEmpty()); -72 } -73 } +41 @Test +42 public void testParse() throws Exception { +43 SAXParserFactory factory = SAXParserFactory.newInstance(); +44 SAXParser saxParser = factory.newSAXParser(); +45 +46 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2012.xml").getPath()); +47 File file = BaseTest.getResourceAsFile(this, "nvdcve-2012.xml"); +48 +49 NvdCve12Handler instance = new NvdCve12Handler(); +50 saxParser.parse(file, instance); +51 Map<String, List<VulnerableSoftware>> results = instance.getVulnerabilities(); +52 assertTrue("No vulnerable software identified with a previous version in 2012 CVE 1.2?", !results.isEmpty()); +53 } +54 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html index 694c8c1d4..f892447bd 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html @@ -27,64 +27,78 @@ 19 20 import org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler; 21 import java.io.File; -22 import javax.xml.parsers.SAXParser; -23 import javax.xml.parsers.SAXParserFactory; -24 import org.junit.After; -25 import org.junit.AfterClass; -26 import static org.junit.Assert.assertTrue; -27 import org.junit.Before; -28 import org.junit.BeforeClass; -29 import org.junit.Test; -30 import org.owasp.dependencycheck.BaseTest; -31 -32 /** -33 * -34 * @author Jeremy Long -35 */ -36 public class NvdCve_2_0_HandlerTest { -37 -38 public NvdCve_2_0_HandlerTest() { -39 } +22 import java.util.List; +23 import java.util.Map; +24 import javax.xml.parsers.SAXParser; +25 import javax.xml.parsers.SAXParserFactory; +26 import org.junit.After; +27 import org.junit.AfterClass; +28 import static org.junit.Assert.assertTrue; +29 import org.junit.Before; +30 import org.junit.BeforeClass; +31 import org.junit.Test; +32 import org.owasp.dependencycheck.BaseTest; +33 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +34 +35 /** +36 * +37 * @author Jeremy Long +38 */ +39 public class NvdCve_2_0_HandlerTest extends BaseTest { 40 -41 @BeforeClass -42 public static void setUpClass() throws Exception { -43 } -44 -45 @AfterClass -46 public static void tearDownClass() throws Exception { -47 } -48 -49 @Before -50 public void setUp() { -51 } +41 @Test +42 public void testParse() { +43 Throwable results = null; +44 try { +45 SAXParserFactory factory = SAXParserFactory.newInstance(); +46 SAXParser saxParser = factory.newSAXParser(); +47 +48 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); +49 File file = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2012.xml"); +50 +51 NvdCve20Handler instance = new NvdCve20Handler(); 52 -53 @After -54 public void tearDown() { -55 } -56 -57 @Test -58 public void testParse() { -59 Throwable results = null; -60 try { -61 SAXParserFactory factory = SAXParserFactory.newInstance(); -62 SAXParser saxParser = factory.newSAXParser(); +53 saxParser.parse(file, instance); +54 } catch (Throwable ex) { +55 ex.printStackTrace(); +56 results = ex; +57 } +58 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); +59 if (results != null) { +60 System.err.println(results); +61 } +62 } 63 -64 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); -65 File file = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2012.xml"); -66 -67 NvdCve20Handler instance = new NvdCve20Handler(); -68 -69 saxParser.parse(file, instance); -70 } catch (Throwable ex) { -71 results = ex; -72 } -73 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); -74 if (results != null) { -75 System.err.println(results); -76 } -77 -78 } -79 } +64 @Test +65 public void testParserWithPreviousVersion() { +66 Throwable results = null; +67 try { +68 SAXParserFactory factory = SAXParserFactory.newInstance(); +69 SAXParser saxParser = factory.newSAXParser(); +70 +71 File file12 = BaseTest.getResourceAsFile(this, "cve-1.2-2008_4411.xml"); +72 +73 final NvdCve12Handler cve12Handler = new NvdCve12Handler(); +74 saxParser.parse(file12, cve12Handler); +75 final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities(); +76 +77 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); +78 File file20 = BaseTest.getResourceAsFile(this, "cve-2.0-2008_4411.xml"); +79 +80 NvdCve20Handler instance = new NvdCve20Handler(); +81 instance.setPrevVersionVulnMap(prevVersionVulnMap); +82 saxParser.parse(file20, instance); +83 +84 assertTrue(instance.getTotalNumberOfEntries()==1); +85 } catch (Throwable ex) { +86 results = ex; +87 } +88 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); +89 if (results != null) { +90 System.err.println(results); +91 } +92 } +93 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html index 122a53a82..5fac37a40 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html index 499e3693e..8c9ee5602 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-frame.html index b9d7870cc..b5dba740f 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-summary.html index 98b6f30ac..b3e35edd9 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html index 57553ab8c..5016a0f4e 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html @@ -43,282 +43,263 @@ 35 * 36 * @author Jeremy Long 37 */ -38 public class DependencyTest { +38 public class DependencyTest extends BaseTest { 39 -40 public DependencyTest() { -41 } -42 -43 @BeforeClass -44 public static void setUpClass() throws Exception { -45 } -46 -47 @AfterClass -48 public static void tearDownClass() throws Exception { -49 } -50 -51 @Before -52 public void setUp() { -53 } -54 -55 @After -56 public void tearDown() { -57 } -58 -59 /** -60 * Test of getFileName method, of class Dependency. -61 */ -62 @Test -63 public void testGetFileName() { -64 Dependency instance = new Dependency(); -65 String expResult = "filename"; -66 instance.setFileName(expResult); -67 String result = instance.getFileName(); -68 assertEquals(expResult, result); -69 } -70 -71 /** -72 * Test of setFileName method, of class Dependency. -73 */ -74 @Test -75 public void testSetFileName() { -76 String fileName = "file.tar"; -77 Dependency instance = new Dependency(); -78 instance.setFileName(fileName); -79 assertEquals(fileName, instance.getFileName()); -80 } -81 -82 /** -83 * Test of setActualFilePath method, of class Dependency. -84 */ -85 @Test -86 public void testSetActualFilePath() { -87 String actualFilePath = "file.tar"; -88 Dependency instance = new Dependency(); -89 instance.setSha1sum("non-null value"); -90 instance.setActualFilePath(actualFilePath); -91 assertEquals(actualFilePath, instance.getActualFilePath()); -92 } -93 -94 /** -95 * Test of getActualFilePath method, of class Dependency. -96 */ -97 @Test -98 public void testGetActualFilePath() { -99 Dependency instance = new Dependency(); -100 String expResult = "file.tar"; -101 instance.setSha1sum("non-null value"); -102 instance.setActualFilePath(expResult); -103 String result = instance.getActualFilePath(); -104 assertEquals(expResult, result); -105 } -106 -107 /** -108 * Test of setFilePath method, of class Dependency. -109 */ -110 @Test -111 public void testSetFilePath() { -112 String filePath = "file.tar"; -113 Dependency instance = new Dependency(); -114 instance.setFilePath(filePath); -115 assertEquals(filePath, instance.getFilePath()); -116 } -117 -118 /** -119 * Test of getFilePath method, of class Dependency. -120 */ -121 @Test -122 public void testGetFilePath() { -123 Dependency instance = new Dependency(); -124 String expResult = "file.tar"; -125 instance.setFilePath(expResult); -126 String result = instance.getFilePath(); -127 assertEquals(expResult, result); -128 } -129 -130 /** -131 * Test of getMd5sum method, of class Dependency. -132 */ -133 @Test -134 public void testGetMd5sum() { -135 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -136 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +40 /** +41 * Test of getFileName method, of class Dependency. +42 */ +43 @Test +44 public void testGetFileName() { +45 Dependency instance = new Dependency(); +46 String expResult = "filename"; +47 instance.setFileName(expResult); +48 String result = instance.getFileName(); +49 assertEquals(expResult, result); +50 } +51 +52 /** +53 * Test of setFileName method, of class Dependency. +54 */ +55 @Test +56 public void testSetFileName() { +57 String fileName = "file.tar"; +58 Dependency instance = new Dependency(); +59 instance.setFileName(fileName); +60 assertEquals(fileName, instance.getFileName()); +61 } +62 +63 /** +64 * Test of setActualFilePath method, of class Dependency. +65 */ +66 @Test +67 public void testSetActualFilePath() { +68 String actualFilePath = "file.tar"; +69 Dependency instance = new Dependency(); +70 instance.setSha1sum("non-null value"); +71 instance.setActualFilePath(actualFilePath); +72 assertEquals(actualFilePath, instance.getActualFilePath()); +73 } +74 +75 /** +76 * Test of getActualFilePath method, of class Dependency. +77 */ +78 @Test +79 public void testGetActualFilePath() { +80 Dependency instance = new Dependency(); +81 String expResult = "file.tar"; +82 instance.setSha1sum("non-null value"); +83 instance.setActualFilePath(expResult); +84 String result = instance.getActualFilePath(); +85 assertEquals(expResult, result); +86 } +87 +88 /** +89 * Test of setFilePath method, of class Dependency. +90 */ +91 @Test +92 public void testSetFilePath() { +93 String filePath = "file.tar"; +94 Dependency instance = new Dependency(); +95 instance.setFilePath(filePath); +96 assertEquals(filePath, instance.getFilePath()); +97 } +98 +99 /** +100 * Test of getFilePath method, of class Dependency. +101 */ +102 @Test +103 public void testGetFilePath() { +104 Dependency instance = new Dependency(); +105 String expResult = "file.tar"; +106 instance.setFilePath(expResult); +107 String result = instance.getFilePath(); +108 assertEquals(expResult, result); +109 } +110 +111 /** +112 * Test of getMd5sum method, of class Dependency. +113 */ +114 @Test +115 public void testGetMd5sum() { +116 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +117 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +118 +119 Dependency instance = new Dependency(file); +120 //assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); +121 //String expResult = "C30B57142E1CCBC1EFD5CD15F307358F"; +122 String expResult = "c30b57142e1ccbc1efd5cd15f307358f"; +123 String result = instance.getMd5sum(); +124 assertEquals(expResult, result); +125 } +126 +127 /** +128 * Test of setMd5sum method, of class Dependency. +129 */ +130 @Test +131 public void testSetMd5sum() { +132 String md5sum = "test"; +133 Dependency instance = new Dependency(); +134 instance.setMd5sum(md5sum); +135 assertEquals(md5sum, instance.getMd5sum()); +136 } 137 -138 Dependency instance = new Dependency(file); -139 //assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); -140 //String expResult = "C30B57142E1CCBC1EFD5CD15F307358F"; -141 String expResult = "c30b57142e1ccbc1efd5cd15f307358f"; -142 String result = instance.getMd5sum(); -143 assertEquals(expResult, result); -144 } -145 -146 /** -147 * Test of setMd5sum method, of class Dependency. -148 */ -149 @Test -150 public void testSetMd5sum() { -151 String md5sum = "test"; -152 Dependency instance = new Dependency(); -153 instance.setMd5sum(md5sum); -154 assertEquals(md5sum, instance.getMd5sum()); -155 } -156 -157 /** -158 * Test of getSha1sum method, of class Dependency. -159 */ -160 @Test -161 public void testGetSha1sum() { -162 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -163 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -164 Dependency instance = new Dependency(file); -165 //String expResult = "89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B"; -166 String expResult = "89ce9e36aa9a9e03f1450936d2f4f8dd0f961f8b"; -167 String result = instance.getSha1sum(); -168 assertEquals(expResult, result); -169 } +138 /** +139 * Test of getSha1sum method, of class Dependency. +140 */ +141 @Test +142 public void testGetSha1sum() { +143 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +144 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +145 Dependency instance = new Dependency(file); +146 //String expResult = "89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B"; +147 String expResult = "89ce9e36aa9a9e03f1450936d2f4f8dd0f961f8b"; +148 String result = instance.getSha1sum(); +149 assertEquals(expResult, result); +150 } +151 +152 /** +153 * Test of setSha1sum method, of class Dependency. +154 */ +155 @Test +156 public void testSetSha1sum() { +157 String sha1sum = "test"; +158 Dependency instance = new Dependency(); +159 instance.setSha1sum(sha1sum); +160 assertEquals(sha1sum, instance.getSha1sum()); +161 } +162 +163 /** +164 * Test of getIdentifiers method, of class Dependency. +165 */ +166 @Test +167 public void testGetIdentifiers() { +168 Dependency instance = new Dependency(); +169 Set<Identifier> result = instance.getIdentifiers(); 170 -171 /** -172 * Test of setSha1sum method, of class Dependency. -173 */ -174 @Test -175 public void testSetSha1sum() { -176 String sha1sum = "test"; -177 Dependency instance = new Dependency(); -178 instance.setSha1sum(sha1sum); -179 assertEquals(sha1sum, instance.getSha1sum()); -180 } -181 -182 /** -183 * Test of getIdentifiers method, of class Dependency. -184 */ -185 @Test -186 public void testGetIdentifiers() { -187 Dependency instance = new Dependency(); -188 Set<Identifier> result = instance.getIdentifiers(); -189 -190 assertTrue(true); //this is just a getter setter pair. -191 } -192 -193 /** -194 * Test of setIdentifiers method, of class Dependency. -195 */ -196 @Test -197 public void testSetIdentifiers() { -198 Set<Identifier> identifiers = null; -199 Dependency instance = new Dependency(); -200 instance.setIdentifiers(identifiers); -201 assertTrue(true); //this is just a getter setter pair. -202 } -203 -204 /** -205 * Test of addIdentifier method, of class Dependency. -206 */ -207 @Test -208 public void testAddIdentifier() { -209 String type = "cpe"; -210 String value = "cpe:/a:apache:struts:2.1.2"; -211 String url = "http://somewhere"; -212 Identifier expResult = new Identifier(type, value, url); -213 -214 Dependency instance = new Dependency(); -215 instance.addIdentifier(type, value, url); -216 assertEquals(1, instance.getIdentifiers().size()); -217 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); -218 } +171 assertTrue(true); //this is just a getter setter pair. +172 } +173 +174 /** +175 * Test of setIdentifiers method, of class Dependency. +176 */ +177 @Test +178 public void testSetIdentifiers() { +179 Set<Identifier> identifiers = null; +180 Dependency instance = new Dependency(); +181 instance.setIdentifiers(identifiers); +182 assertTrue(true); //this is just a getter setter pair. +183 } +184 +185 /** +186 * Test of addIdentifier method, of class Dependency. +187 */ +188 @Test +189 public void testAddIdentifier() { +190 String type = "cpe"; +191 String value = "cpe:/a:apache:struts:2.1.2"; +192 String url = "http://somewhere"; +193 Identifier expResult = new Identifier(type, value, url); +194 +195 Dependency instance = new Dependency(); +196 instance.addIdentifier(type, value, url); +197 assertEquals(1, instance.getIdentifiers().size()); +198 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); +199 } +200 +201 /** +202 * Test of getEvidence method, of class Dependency. +203 */ +204 @Test +205 public void testGetEvidence() { +206 Dependency instance = new Dependency(); +207 EvidenceCollection expResult = null; +208 EvidenceCollection result = instance.getEvidence(); +209 assertTrue(true); //this is just a getter setter pair. +210 } +211 +212 /** +213 * Test of getEvidenceUsed method, of class Dependency. +214 */ +215 @Test +216 public void testGetEvidenceUsed() { +217 Dependency instance = new Dependency(); +218 String expResult = "used"; 219 -220 /** -221 * Test of getEvidence method, of class Dependency. -222 */ -223 @Test -224 public void testGetEvidence() { -225 Dependency instance = new Dependency(); -226 EvidenceCollection expResult = null; -227 EvidenceCollection result = instance.getEvidence(); -228 assertTrue(true); //this is just a getter setter pair. -229 } -230 -231 /** -232 * Test of getEvidenceUsed method, of class Dependency. -233 */ -234 @Test -235 public void testGetEvidenceUsed() { -236 Dependency instance = new Dependency(); -237 String expResult = "used"; -238 -239 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); -240 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); -241 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { -242 String use = e.getValue(); -243 } -244 -245 EvidenceCollection result = instance.getEvidenceUsed(); -246 -247 assertEquals(1, result.size()); -248 assertTrue(result.containsUsedString(expResult)); -249 } -250 -251 /** -252 * Test of getVendorEvidence method, of class Dependency. -253 */ -254 @Test -255 public void testGetVendorEvidence() { -256 Dependency instance = new Dependency(); -257 EvidenceCollection expResult = null; -258 EvidenceCollection result = instance.getVendorEvidence(); -259 assertTrue(true); //this is just a getter setter pair. -260 } -261 -262 /** -263 * Test of getProductEvidence method, of class Dependency. -264 */ -265 @Test -266 public void testGetProductEvidence() { -267 Dependency instance = new Dependency(); -268 EvidenceCollection expResult = null; -269 EvidenceCollection result = instance.getProductEvidence(); -270 assertTrue(true); //this is just a getter setter pair. -271 } -272 -273 /** -274 * Test of getVersionEvidence method, of class Dependency. -275 */ -276 @Test -277 public void testGetVersionEvidence() { -278 Dependency instance = new Dependency(); -279 EvidenceCollection expResult = null; -280 EvidenceCollection result = instance.getVersionEvidence(); -281 assertTrue(true); //this is just a getter setter pair. -282 } -283 -284 /** -285 * Test of addAsEvidence method, of class Dependency. -286 */ -287 @Test -288 public void testAddAsEvidence() { -289 Dependency instance = new Dependency(); -290 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); -291 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -292 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); -293 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -294 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -295 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -296 assertFalse(instance.getIdentifiers().isEmpty()); -297 } -298 -299 /** -300 * Test of addAsEvidence method, of class Dependency. -301 */ -302 @Test -303 public void testAddAsEvidenceWithEmptyArtefact() { -304 Dependency instance = new Dependency(); -305 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); -306 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -307 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); -308 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -309 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -310 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -311 assertTrue(instance.getIdentifiers().isEmpty()); -312 } -313 } +220 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); +221 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); +222 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { +223 String use = e.getValue(); +224 } +225 +226 EvidenceCollection result = instance.getEvidenceUsed(); +227 +228 assertEquals(1, result.size()); +229 assertTrue(result.containsUsedString(expResult)); +230 } +231 +232 /** +233 * Test of getVendorEvidence method, of class Dependency. +234 */ +235 @Test +236 public void testGetVendorEvidence() { +237 Dependency instance = new Dependency(); +238 EvidenceCollection expResult = null; +239 EvidenceCollection result = instance.getVendorEvidence(); +240 assertTrue(true); //this is just a getter setter pair. +241 } +242 +243 /** +244 * Test of getProductEvidence method, of class Dependency. +245 */ +246 @Test +247 public void testGetProductEvidence() { +248 Dependency instance = new Dependency(); +249 EvidenceCollection expResult = null; +250 EvidenceCollection result = instance.getProductEvidence(); +251 assertTrue(true); //this is just a getter setter pair. +252 } +253 +254 /** +255 * Test of getVersionEvidence method, of class Dependency. +256 */ +257 @Test +258 public void testGetVersionEvidence() { +259 Dependency instance = new Dependency(); +260 EvidenceCollection expResult = null; +261 EvidenceCollection result = instance.getVersionEvidence(); +262 assertTrue(true); //this is just a getter setter pair. +263 } +264 +265 /** +266 * Test of addAsEvidence method, of class Dependency. +267 */ +268 @Test +269 public void testAddAsEvidence() { +270 Dependency instance = new Dependency(); +271 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); +272 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +273 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); +274 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +275 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +276 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +277 assertFalse(instance.getIdentifiers().isEmpty()); +278 } +279 +280 /** +281 * Test of addAsEvidence method, of class Dependency. +282 */ +283 @Test +284 public void testAddAsEvidenceWithEmptyArtefact() { +285 Dependency instance = new Dependency(); +286 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); +287 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +288 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); +289 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +290 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +291 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +292 assertTrue(instance.getIdentifiers().isEmpty()); +293 } +294 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/EvidenceTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/EvidenceTest.html index c5b4d558f..92e63b507 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/EvidenceTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/EvidenceTest.html @@ -28,98 +28,99 @@ 20 import org.junit.Test; 21 import static org.junit.Assert.*; 22 import static org.hamcrest.CoreMatchers.*; -23 -24 /** -25 * -26 * @author Jeremy Long -27 */ -28 public class EvidenceTest { -29 -30 /** -31 * Test of equals method, of class Evidence. -32 */ -33 @Test -34 public void testEquals() { -35 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); -36 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); -37 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); -38 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); -39 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); -40 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); -41 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); -42 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); -43 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -44 -45 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -46 assertFalse(instance.equals(that0)); -47 assertFalse(instance.equals(that1)); -48 assertFalse(instance.equals(that2)); -49 assertFalse(instance.equals(that3)); -50 assertFalse(instance.equals(that4)); -51 assertFalse(instance.equals(that5)); -52 assertFalse(instance.equals(that6)); -53 assertFalse(instance.equals(that7)); -54 assertTrue(instance.equals(that8)); -55 } -56 -57 @Test -58 public void testHashcodeContract() throws Exception { -59 final Evidence titleCase = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -60 final Evidence lowerCase = new Evidence("manifest", "implementation-title", "spring framework", Confidence.HIGH); -61 assertThat(titleCase, is(equalTo(lowerCase))); -62 assertThat(titleCase.hashCode(), is(equalTo(lowerCase.hashCode()))); -63 } -64 -65 /** -66 * Test of compareTo method, of class Evidence. -67 */ -68 @Test -69 public void testCompareTo() { -70 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); -71 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); -72 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); -73 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); -74 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); -75 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); -76 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); -77 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); -78 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -79 -80 Evidence that9 = new Evidence("manifest", "implementation-title", "zippy", Confidence.HIGH); -81 -82 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -83 -84 int result = instance.compareTo(that0); -85 assertTrue(result > 0); -86 -87 result = instance.compareTo(that1); -88 assertTrue(result > 0); -89 -90 result = instance.compareTo(that2); -91 assertTrue(result > 0); -92 -93 result = instance.compareTo(that3); -94 assertTrue(result > 0); -95 -96 result = instance.compareTo(that4); -97 assertTrue(result > 0); -98 -99 result = instance.compareTo(that5); -100 assertTrue(result > 0); -101 -102 result = instance.compareTo(that6); -103 assertTrue(result > 0); -104 -105 result = instance.compareTo(that7); -106 assertTrue(result > 0); -107 -108 result = instance.compareTo(that8); -109 assertTrue(result == 0); -110 -111 result = instance.compareTo(that9); -112 assertTrue(result < 0); -113 } -114 } +23 import org.owasp.dependencycheck.BaseTest; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class EvidenceTest extends BaseTest { +30 +31 /** +32 * Test of equals method, of class Evidence. +33 */ +34 @Test +35 public void testEquals() { +36 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); +37 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); +38 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); +39 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); +40 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); +41 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); +42 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); +43 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); +44 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +45 +46 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +47 assertFalse(instance.equals(that0)); +48 assertFalse(instance.equals(that1)); +49 assertFalse(instance.equals(that2)); +50 assertFalse(instance.equals(that3)); +51 assertFalse(instance.equals(that4)); +52 assertFalse(instance.equals(that5)); +53 assertFalse(instance.equals(that6)); +54 assertFalse(instance.equals(that7)); +55 assertTrue(instance.equals(that8)); +56 } +57 +58 @Test +59 public void testHashcodeContract() throws Exception { +60 final Evidence titleCase = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +61 final Evidence lowerCase = new Evidence("manifest", "implementation-title", "spring framework", Confidence.HIGH); +62 assertThat(titleCase, is(equalTo(lowerCase))); +63 assertThat(titleCase.hashCode(), is(equalTo(lowerCase.hashCode()))); +64 } +65 +66 /** +67 * Test of compareTo method, of class Evidence. +68 */ +69 @Test +70 public void testCompareTo() { +71 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); +72 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); +73 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); +74 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); +75 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); +76 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); +77 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); +78 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); +79 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +80 +81 Evidence that9 = new Evidence("manifest", "implementation-title", "zippy", Confidence.HIGH); +82 +83 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +84 +85 int result = instance.compareTo(that0); +86 assertTrue(result > 0); +87 +88 result = instance.compareTo(that1); +89 assertTrue(result > 0); +90 +91 result = instance.compareTo(that2); +92 assertTrue(result > 0); +93 +94 result = instance.compareTo(that3); +95 assertTrue(result > 0); +96 +97 result = instance.compareTo(that4); +98 assertTrue(result > 0); +99 +100 result = instance.compareTo(that5); +101 assertTrue(result > 0); +102 +103 result = instance.compareTo(that6); +104 assertTrue(result > 0); +105 +106 result = instance.compareTo(that7); +107 assertTrue(result > 0); +108 +109 result = instance.compareTo(that8); +110 assertTrue(result == 0); +111 +112 result = instance.compareTo(that9); +113 assertTrue(result < 0); +114 } +115 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html new file mode 100644 index 000000000..ceb4706a0 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html @@ -0,0 +1,174 @@ + + + +VulnerabilityTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +3    *
      +4    * Licensed under the Apache License, Version 2.0 (the "License");
      +5    * you may not use this file except in compliance with the License.
      +6    * You may obtain a copy of the License at
      +7    *
      +8    *     http://www.apache.org/licenses/LICENSE-2.0
      +9    *
      +10   * Unless required by applicable law or agreed to in writing, software
      +11   * distributed under the License is distributed on an "AS IS" BASIS,
      +12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      +13   * See the License for the specific language governing permissions and
      +14   * limitations under the License.
      +15   *
      +16   * Copyright (c) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.dependency;
      +19  
      +20  import java.util.Set;
      +21  import org.junit.After;
      +22  import org.junit.AfterClass;
      +23  import static org.junit.Assert.assertEquals;
      +24  import static org.junit.Assert.assertTrue;
      +25  import static org.junit.Assert.assertFalse;
      +26  import org.junit.Before;
      +27  import org.junit.BeforeClass;
      +28  import org.junit.Test;
      +29  import org.owasp.dependencycheck.BaseTest;
      +30  
      +31  /**
      +32   *
      +33   * @author Jens Hausherr
      +34   */
      +35  public class VulnerabilityTest extends BaseTest {
      +36  
      +37      /**
      +38       * Test of equals method, of class VulnerableSoftware.
      +39       */
      +40      @Test
      +41      public void testDuplicateVersions() {
      +42          Vulnerability obj = new Vulnerability();
      +43  
      +44          obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0");
      +45          obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.1");
      +46          obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0");
      +47  
      +48          assertEquals(2, obj.getVulnerableSoftware().size());
      +49      }
      +50  
      +51      @Test
      +52      public void testDpulicateVersionsWithPreviousVersion() {
      +53          Vulnerability obj = new Vulnerability();
      +54          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null);
      +55          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null);
      +56          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null);
      +57          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null);
      +58          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null);
      +59          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null);
      +60          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null);
      +61          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null);
      +62          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null);
      +63          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null);
      +64          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null);
      +65          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null);
      +66          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null);
      +67          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null);
      +68          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null);
      +69          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null);
      +70          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null);
      +71          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null);
      +72          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null);
      +73          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null);
      +74          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null);
      +75          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null);
      +76          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null);
      +77          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null);
      +78          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null);
      +79          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null);
      +80          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null);
      +81          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null);
      +82          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null);
      +83          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null);
      +84          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null);
      +85          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", "1");
      +86          assertEquals(31, obj.getVulnerableSoftware().size());
      +87      }
      +88  
      +89      @Test
      +90      public void testSoftwareSorting() {
      +91          Vulnerability obj = new Vulnerability();
      +92          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null);
      +93          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null);
      +94          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null);
      +95          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null);
      +96          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null);
      +97          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null);
      +98          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null);
      +99          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null);
      +100         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null);
      +101         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null);
      +102         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null);
      +103         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null);
      +104         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null);
      +105         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null);
      +106         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null);
      +107         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null);
      +108         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null);
      +109         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null);
      +110         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null);
      +111         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null);
      +112         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null);
      +113         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null);
      +114         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null);
      +115         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null);
      +116         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null);
      +117         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null);
      +118         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null);
      +119         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null);
      +120         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null);
      +121         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null);
      +122         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null);
      +123 
      +124         Set<VulnerableSoftware> software = obj.getVulnerableSoftware();
      +125         VulnerableSoftware vs[] = software.toArray(new VulnerableSoftware[software.size()]);
      +126 
      +127         assertTrue("cpe:/a:hp:system_management_homepage:2.0.0".equals(vs[0].getName()));
      +128         assertTrue("cpe:/a:hp:system_management_homepage:2.0.1".equals(vs[1].getName()));
      +129         assertTrue("cpe:/a:hp:system_management_homepage:2.0.2".equals(vs[2].getName()));
      +130         assertTrue("cpe:/a:hp:system_management_homepage:2.1".equals(vs[3].getName()));
      +131         assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103".equals(vs[4].getName()));
      +132         assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29".equals(vs[5].getName()));
      +133         assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-109".equals(vs[6].getName()));
      +134         assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-118".equals(vs[7].getName()));
      +135         assertTrue("cpe:/a:hp:system_management_homepage:2.1.1".equals(vs[8].getName()));
      +136         assertTrue("cpe:/a:hp:system_management_homepage:2.1.2".equals(vs[9].getName()));
      +137         assertTrue("cpe:/a:hp:system_management_homepage:2.1.2-127".equals(vs[10].getName()));
      +138         assertTrue("cpe:/a:hp:system_management_homepage:2.1.3".equals(vs[11].getName()));
      +139         assertTrue("cpe:/a:hp:system_management_homepage:2.1.3.132".equals(vs[12].getName()));
      +140         assertTrue("cpe:/a:hp:system_management_homepage:2.1.4".equals(vs[13].getName()));
      +141         assertTrue("cpe:/a:hp:system_management_homepage:2.1.4-143".equals(vs[14].getName()));
      +142         assertTrue("cpe:/a:hp:system_management_homepage:2.1.5".equals(vs[15].getName()));
      +143         assertTrue("cpe:/a:hp:system_management_homepage:2.1.5-146".equals(vs[16].getName()));
      +144         assertTrue("cpe:/a:hp:system_management_homepage:2.1.6".equals(vs[17].getName()));
      +145         assertTrue("cpe:/a:hp:system_management_homepage:2.1.6-156".equals(vs[18].getName()));
      +146         assertTrue("cpe:/a:hp:system_management_homepage:2.1.7".equals(vs[19].getName()));
      +147         assertTrue("cpe:/a:hp:system_management_homepage:2.1.7-168".equals(vs[20].getName()));
      +148         assertTrue("cpe:/a:hp:system_management_homepage:2.1.8".equals(vs[21].getName()));
      +149         assertTrue("cpe:/a:hp:system_management_homepage:2.1.8-177".equals(vs[22].getName()));
      +150         assertTrue("cpe:/a:hp:system_management_homepage:2.1.9".equals(vs[23].getName()));
      +151         assertTrue("cpe:/a:hp:system_management_homepage:2.1.9-178".equals(vs[24].getName()));
      +152         assertTrue("cpe:/a:hp:system_management_homepage:2.1.10".equals(vs[25].getName()));
      +153         assertTrue("cpe:/a:hp:system_management_homepage:2.1.10-186".equals(vs[26].getName()));
      +154         assertTrue("cpe:/a:hp:system_management_homepage:2.1.11".equals(vs[27].getName()));
      +155         assertTrue("cpe:/a:hp:system_management_homepage:2.1.11-197".equals(vs[28].getName()));
      +156         assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-118".equals(vs[29].getName()));
      +157         assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-200".equals(vs[30].getName()));
      +158         
      +159     }
      +160 
      +161 }
      +
      +
      + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html index 42b22f787..a7afdef9f 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html @@ -28,83 +28,138 @@ 20 import org.junit.After; 21 import org.junit.AfterClass; 22 import static org.junit.Assert.assertEquals; -23 import org.junit.Before; -24 import org.junit.BeforeClass; -25 import org.junit.Test; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class VulnerableSoftwareTest { -32 -33 public VulnerableSoftwareTest() { -34 } +23 import static org.junit.Assert.assertTrue; +24 import static org.junit.Assert.assertFalse; +25 import org.junit.Before; +26 import org.junit.BeforeClass; +27 import org.junit.Test; +28 import org.owasp.dependencycheck.BaseTest; +29 +30 /** +31 * +32 * @author Jeremy Long +33 */ +34 public class VulnerableSoftwareTest extends BaseTest { 35 -36 @BeforeClass -37 public static void setUpClass() throws Exception { -38 } -39 -40 @AfterClass -41 public static void tearDownClass() throws Exception { -42 } -43 -44 @Before -45 public void setUp() { +36 /** +37 * Test of equals method, of class VulnerableSoftware. +38 */ +39 @Test +40 public void testEquals() { +41 VulnerableSoftware obj = new VulnerableSoftware(); +42 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +43 VulnerableSoftware instance = new VulnerableSoftware(); +44 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +45 assertFalse(instance.equals(obj)); 46 } 47 -48 @After -49 public void tearDown() { -50 } -51 -52 /** -53 * Test of equals method, of class VulnerableSoftware. -54 */ -55 @Test -56 public void testEquals() { -57 VulnerableSoftware obj = new VulnerableSoftware(); -58 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -59 VulnerableSoftware instance = new VulnerableSoftware(); -60 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -61 boolean expResult = false; -62 boolean result = instance.equals(obj); -63 assertEquals(expResult, result); -64 } -65 -66 /** -67 * Test of hashCode method, of class VulnerableSoftware. -68 */ -69 @Test -70 public void testHashCode() { -71 VulnerableSoftware instance = new VulnerableSoftware(); -72 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -73 int expResult = 1849413912; -74 int result = instance.hashCode(); -75 assertEquals(expResult, result); -76 } -77 -78 /** -79 * Test of compareTo method, of class VulnerableSoftware. -80 */ -81 @Test -82 public void testCompareTo() { -83 VulnerableSoftware vs = new VulnerableSoftware(); -84 vs.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -85 VulnerableSoftware instance = new VulnerableSoftware(); -86 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -87 int expResult = -2; -88 int result = instance.compareTo(vs); -89 assertEquals(expResult, result); -90 -91 vs = new VulnerableSoftware(); -92 vs.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024103"); -93 instance = new VulnerableSoftware(); -94 instance.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024104"); -95 expResult = 1; -96 result = instance.compareTo(vs); -97 assertEquals(expResult, result); -98 } -99 } +48 /** +49 * Test of equals method, of class VulnerableSoftware. +50 */ +51 @Test +52 public void testEquals2() { +53 VulnerableSoftware obj = new VulnerableSoftware(); +54 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +55 VulnerableSoftware instance = new VulnerableSoftware(); +56 instance.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +57 obj.setPreviousVersion("1"); +58 assertTrue(instance.equals(obj)); +59 } +60 +61 /** +62 * Test of hashCode method, of class VulnerableSoftware. +63 */ +64 @Test +65 public void testHashCode() { +66 VulnerableSoftware instance = new VulnerableSoftware(); +67 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +68 int expResult = 1849413912; +69 int result = instance.hashCode(); +70 assertEquals(expResult, result); +71 } +72 +73 /** +74 * Test of compareTo method, of class VulnerableSoftware. +75 */ +76 @Test +77 public void testCompareTo() { +78 VulnerableSoftware vs = new VulnerableSoftware(); +79 vs.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +80 VulnerableSoftware instance = new VulnerableSoftware(); +81 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +82 int expResult = -2; +83 int result = instance.compareTo(vs); +84 assertEquals(expResult, result); +85 +86 vs = new VulnerableSoftware(); +87 vs.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024103"); +88 instance = new VulnerableSoftware(); +89 instance.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024104"); +90 expResult = 1; +91 result = instance.compareTo(vs); +92 assertEquals(expResult, result); +93 } +94 +95 @Test +96 public void testCompareToNonNumerical() { +97 VulnerableSoftware vs = new VulnerableSoftware(); +98 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +99 VulnerableSoftware vs1 = new VulnerableSoftware(); +100 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +101 vs1.setPreviousVersion("1"); +102 assertEquals(0, vs.compareTo(vs1)); +103 assertEquals(0, vs1.compareTo(vs)); +104 } +105 +106 @Test +107 public void testCompareToComplex() { +108 VulnerableSoftware vs = new VulnerableSoftware(); +109 VulnerableSoftware vs1 = new VulnerableSoftware(); +110 +111 vs.setCpe("2.1"); +112 vs1.setCpe("2.1.10"); +113 assertTrue(vs.compareTo(vs1) < 0); +114 +115 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.1"); +116 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); +117 assertTrue(vs.compareTo(vs1) < 0); +118 +119 vs.setCpe("10"); +120 vs1.setCpe("10-186"); +121 assertTrue(vs.compareTo(vs1) < 0); +122 +123 vs.setCpe("2.1.10"); +124 vs1.setCpe("2.1.10-186"); +125 assertTrue(vs.compareTo(vs1) < 0); +126 +127 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); +128 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10-186"); +129 assertTrue(vs.compareTo(vs1) < 0); +130 //assertTrue(vs1.compareTo(vs)>0); +131 } +132 +133 @Test +134 public void testEqualsPreviousVersion() { +135 VulnerableSoftware vs = new VulnerableSoftware(); +136 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +137 VulnerableSoftware vs1 = new VulnerableSoftware(); +138 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +139 vs1.setPreviousVersion("1"); +140 assertEquals(vs, vs1); +141 assertEquals(vs1, vs); +142 +143 } +144 +145 @Test +146 public void testParseCPE() { +147 VulnerableSoftware vs = new VulnerableSoftware(); +148 /* Version for test taken from CVE-2008-2079 */ +149 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +150 assertEquals("mysql", vs.getVendor()); +151 assertEquals("mysql", vs.getProduct()); +152 assertEquals("5.1.23a", vs.getVersion()); +153 } +154 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-frame.html index c9eb89ea0..3fd533653 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.dependency @@ -20,6 +20,9 @@
    62. EvidenceTest +
    63. +
    64. + VulnerabilityTest
    65. VulnerableSoftwareTest diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-summary.html index 25d9f3c87..eaf133384 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.dependency @@ -44,6 +44,11 @@ EvidenceTest + + + + VulnerabilityTest + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/package-frame.html index 30bcb85ac..b10a76da8 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/package-summary.html index 0e465a813..4de0d840e 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html index 12d3e3b01..89534aafb 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html @@ -34,136 +34,132 @@ 26 import javax.xml.validation.Validator; 27 import org.junit.Before; 28 import org.junit.Test; -29 import org.owasp.dependencycheck.BaseTest; -30 import org.owasp.dependencycheck.Engine; -31 import org.owasp.dependencycheck.data.nvdcve.CveDB; -32 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -33 import org.owasp.dependencycheck.utils.Settings; -34 -35 /** -36 * -37 * @author Jeremy Long -38 */ -39 public class ReportGeneratorIntegrationTest extends BaseTest { -40 -41 @Before -42 public void setUp() throws Exception { -43 org.owasp.dependencycheck.BaseDBTestCase.ensureDBExists(); -44 } -45 -46 /** -47 * Test of generateReport method, of class ReportGenerator. -48 * -49 * @throws Exception is thrown when an exception occurs. -50 */ -51 @Test -52 public void testGenerateReport() throws Exception { -53 String templateName = "HtmlReport"; -54 // File f = new File("target/test-reports"); -55 // if (!f.exists()) { -56 // f.mkdir(); -57 // } -58 // String writeTo = "target/test-reports/Report.html"; -59 // Map<String, Object> properties = new HashMap<String, Object>(); -60 // Dependency d = new Dependency(); -61 // d.setFileName("FileName.jar"); -62 // d.setActualFilePath("lib/FileName.jar"); -63 // d.addCPEentry("cpe://a:/some:cpe:1.0"); +29 import org.owasp.dependencycheck.BaseDBTestCase; +30 import org.owasp.dependencycheck.BaseTest; +31 import org.owasp.dependencycheck.Engine; +32 import org.owasp.dependencycheck.data.nvdcve.CveDB; +33 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +34 import org.owasp.dependencycheck.utils.Settings; +35 +36 /** +37 * +38 * @author Jeremy Long +39 */ +40 public class ReportGeneratorIntegrationTest extends BaseDBTestCase { +41 +42 /** +43 * Test of generateReport method, of class ReportGenerator. +44 * +45 * @throws Exception is thrown when an exception occurs. +46 */ +47 @Test +48 public void testGenerateReport() throws Exception { +49 String templateName = "HtmlReport"; +50 // File f = new File("target/test-reports"); +51 // if (!f.exists()) { +52 // f.mkdir(); +53 // } +54 // String writeTo = "target/test-reports/Report.html"; +55 // Map<String, Object> properties = new HashMap<String, Object>(); +56 // Dependency d = new Dependency(); +57 // d.setFileName("FileName.jar"); +58 // d.setActualFilePath("lib/FileName.jar"); +59 // d.addCPEentry("cpe://a:/some:cpe:1.0"); +60 // +61 // List<Dependency> dependencies = new ArrayList<Dependency>(); +62 // d.getProductEvidence().addEvidence("jar","filename","<test>test", Confidence.HIGH); +63 // d.getProductEvidence().addEvidence("manifest","vendor","<test>test", Confidence.HIGH); 64 // -65 // List<Dependency> dependencies = new ArrayList<Dependency>(); -66 // d.getProductEvidence().addEvidence("jar","filename","<test>test", Confidence.HIGH); -67 // d.getProductEvidence().addEvidence("manifest","vendor","<test>test", Confidence.HIGH); -68 // -69 // for (Evidence e : d.getProductEvidence().iterator(Confidence.HIGH)) { -70 // String t = e.getValue(); -71 // } -72 // dependencies.add(d); -73 // -74 // Dependency d2 = new Dependency(); -75 // d2.setFileName("Another.jar"); -76 // d2.setActualFilePath("lib/Another.jar"); -77 // d2.addCPEentry("cpe://a:/another:cpe:1.0"); -78 // d2.addCPEentry("cpe://a:/another:cpe:1.1"); -79 // d2.addCPEentry("cpe://a:/another:cpe:1.2"); -80 // d2.getProductEvidence().addEvidence("jar","filename","another.jar", Confidence.HIGH); -81 // d2.getProductEvidence().addEvidence("manifest","vendor","Company A", Confidence.MEDIUM); +65 // for (Evidence e : d.getProductEvidence().iterator(Confidence.HIGH)) { +66 // String t = e.getValue(); +67 // } +68 // dependencies.add(d); +69 // +70 // Dependency d2 = new Dependency(); +71 // d2.setFileName("Another.jar"); +72 // d2.setActualFilePath("lib/Another.jar"); +73 // d2.addCPEentry("cpe://a:/another:cpe:1.0"); +74 // d2.addCPEentry("cpe://a:/another:cpe:1.1"); +75 // d2.addCPEentry("cpe://a:/another:cpe:1.2"); +76 // d2.getProductEvidence().addEvidence("jar","filename","another.jar", Confidence.HIGH); +77 // d2.getProductEvidence().addEvidence("manifest","vendor","Company A", Confidence.MEDIUM); +78 // +79 // for (Evidence e : d2.getProductEvidence().iterator(Confidence.HIGH)) { +80 // String t = e.getValue(); +81 // } 82 // -83 // for (Evidence e : d2.getProductEvidence().iterator(Confidence.HIGH)) { -84 // String t = e.getValue(); -85 // } -86 // -87 // dependencies.add(d2); -88 // -89 // Dependency d3 = new Dependency(); -90 // d3.setFileName("Third.jar"); -91 // d3.setActualFilePath("lib/Third.jar"); -92 // d3.getProductEvidence().addEvidence("jar","filename","third.jar", Confidence.HIGH); +83 // dependencies.add(d2); +84 // +85 // Dependency d3 = new Dependency(); +86 // d3.setFileName("Third.jar"); +87 // d3.setActualFilePath("lib/Third.jar"); +88 // d3.getProductEvidence().addEvidence("jar","filename","third.jar", Confidence.HIGH); +89 // +90 // for (Evidence e : d3.getProductEvidence().iterator(Confidence.HIGH)) { +91 // String t = e.getValue(); +92 // } 93 // -94 // for (Evidence e : d3.getProductEvidence().iterator(Confidence.HIGH)) { -95 // String t = e.getValue(); -96 // } +94 // dependencies.add(d3); +95 // +96 // properties.put("dependencies",dependencies); 97 // -98 // dependencies.add(d3); -99 // -100 // properties.put("dependencies",dependencies); -101 // -102 // ReportGenerator instance = new ReportGenerator(); -103 // instance.generateReport(templateName, writeTo, properties); -104 //assertTrue("need to add a real check here", false); -105 } -106 -107 /** -108 * Generates an XML report containing known vulnerabilities and realistic data and validates the generated XML document -109 * against the XSD. -110 * -111 * @throws Exception -112 */ -113 @Test -114 public void testGenerateXMLReport() throws Exception { -115 String templateName = "XmlReport"; -116 -117 File f = new File("target/test-reports"); -118 if (!f.exists()) { -119 f.mkdir(); -120 } -121 String writeTo = "target/test-reports/Report.xml"; -122 -123 //File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -124 File struts = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -125 //File axis = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath()); -126 File axis = BaseTest.getResourceAsFile(this, "axis2-adb-1.4.1.jar"); -127 //File jetty = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); -128 File jetty = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar"); -129 -130 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -131 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -132 Engine engine = new Engine(); -133 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -134 -135 engine.scan(struts); -136 engine.scan(axis); -137 engine.scan(jetty); -138 engine.analyzeDependencies(); -139 -140 CveDB cveDB = new CveDB(); -141 cveDB.open(); -142 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); -143 cveDB.close(); -144 -145 ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp); -146 generator.generateReport(templateName, writeTo); -147 -148 engine.cleanup(); -149 -150 InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/dependency-check.1.3.xsd"); -151 StreamSource xsdSource = new StreamSource(xsdStream); -152 StreamSource xmlSource = new StreamSource(new File(writeTo)); -153 SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); -154 Schema schema = sf.newSchema(xsdSource); -155 Validator validator = schema.newValidator(); -156 validator.validate(xmlSource); -157 } -158 } +98 // ReportGenerator instance = new ReportGenerator(); +99 // instance.generateReport(templateName, writeTo, properties); +100 //assertTrue("need to add a real check here", false); +101 } +102 +103 /** +104 * Generates an XML report containing known vulnerabilities and realistic data and validates the generated XML document +105 * against the XSD. +106 * +107 * @throws Exception +108 */ +109 @Test +110 public void testGenerateXMLReport() throws Exception { +111 String templateName = "XmlReport"; +112 +113 File f = new File("target/test-reports"); +114 if (!f.exists()) { +115 f.mkdir(); +116 } +117 String writeTo = "target/test-reports/Report.xml"; +118 +119 //File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +120 File struts = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +121 //File axis = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath()); +122 File axis = BaseTest.getResourceAsFile(this, "axis2-adb-1.4.1.jar"); +123 //File jetty = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); +124 File jetty = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar"); +125 +126 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +127 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +128 Engine engine = new Engine(); +129 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +130 +131 engine.scan(struts); +132 engine.scan(axis); +133 engine.scan(jetty); +134 engine.analyzeDependencies(); +135 +136 CveDB cveDB = new CveDB(); +137 cveDB.open(); +138 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); +139 cveDB.close(); +140 +141 ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp); +142 generator.generateReport(templateName, writeTo); +143 +144 engine.cleanup(); +145 +146 InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/dependency-check.1.3.xsd"); +147 StreamSource xsdSource = new StreamSource(xsdStream); +148 StreamSource xmlSource = new StreamSource(new File(writeTo)); +149 SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); +150 Schema schema = sf.newSchema(xsdSource); +151 Validator validator = schema.newValidator(); +152 validator.validate(xmlSource); +153 } +154 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-frame.html index facb42cb9..78fb460bd 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.reporting diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-summary.html index a25ddcc01..67a4c5f86 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.reporting diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/PropertyTypeTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/PropertyTypeTest.html index 3338b4907..1c7dceee9 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/PropertyTypeTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/PropertyTypeTest.html @@ -33,88 +33,70 @@ 25 import org.junit.Before; 26 import org.junit.BeforeClass; 27 import org.junit.Test; -28 -29 /** -30 * -31 * @author Jeremy Long -32 */ -33 public class PropertyTypeTest { -34 -35 public PropertyTypeTest() { -36 } -37 -38 @BeforeClass -39 public static void setUpClass() { -40 } +28 import org.owasp.dependencycheck.BaseTest; +29 +30 /** +31 * +32 * @author Jeremy Long +33 */ +34 public class PropertyTypeTest extends BaseTest { +35 +36 /** +37 * Test of set and getValue method, of class PropertyType. +38 */ +39 @Test +40 public void testSetGetValue() { 41 -42 @AfterClass -43 public static void tearDownClass() { -44 } -45 -46 @Before -47 public void setUp() { -48 } -49 -50 @After -51 public void tearDown() { -52 } -53 -54 /** -55 * Test of set and getValue method, of class PropertyType. -56 */ -57 @Test -58 public void testSetGetValue() { -59 -60 PropertyType instance = new PropertyType(); -61 String expResult = "test"; -62 instance.setValue(expResult); -63 String result = instance.getValue(); -64 assertEquals(expResult, result); -65 } -66 -67 /** -68 * Test of isRegex method, of class PropertyType. -69 */ -70 @Test -71 public void testIsRegex() { -72 PropertyType instance = new PropertyType(); -73 boolean result = instance.isRegex(); -74 assertFalse(instance.isRegex()); -75 instance.setRegex(true); -76 assertTrue(instance.isRegex()); -77 } +42 PropertyType instance = new PropertyType(); +43 String expResult = "test"; +44 instance.setValue(expResult); +45 String result = instance.getValue(); +46 assertEquals(expResult, result); +47 } +48 +49 /** +50 * Test of isRegex method, of class PropertyType. +51 */ +52 @Test +53 public void testIsRegex() { +54 PropertyType instance = new PropertyType(); +55 boolean result = instance.isRegex(); +56 assertFalse(instance.isRegex()); +57 instance.setRegex(true); +58 assertTrue(instance.isRegex()); +59 } +60 +61 /** +62 * Test of isCaseSensitive method, of class PropertyType. +63 */ +64 @Test +65 public void testIsCaseSensitive() { +66 PropertyType instance = new PropertyType(); +67 assertFalse(instance.isCaseSensitive()); +68 instance.setCaseSensitive(true); +69 assertTrue(instance.isCaseSensitive()); +70 } +71 +72 /** +73 * Test of matches method, of class PropertyType. +74 */ +75 @Test +76 public void testMatches() { +77 String text = "Simple"; 78 -79 /** -80 * Test of isCaseSensitive method, of class PropertyType. -81 */ -82 @Test -83 public void testIsCaseSensitive() { -84 PropertyType instance = new PropertyType(); -85 assertFalse(instance.isCaseSensitive()); -86 instance.setCaseSensitive(true); -87 assertTrue(instance.isCaseSensitive()); -88 } -89 -90 /** -91 * Test of matches method, of class PropertyType. -92 */ -93 @Test -94 public void testMatches() { -95 String text = "Simple"; -96 -97 PropertyType instance = new PropertyType(); -98 instance.setValue("simple"); -99 assertTrue(instance.matches(text)); -100 instance.setCaseSensitive(true); -101 assertFalse(instance.matches(text)); -102 -103 instance.setValue("s.*le"); -104 instance.setRegex(true); -105 assertFalse(instance.matches(text)); -106 instance.setCaseSensitive(false); -107 assertTrue(instance.matches(text)); -108 } -109 } +79 PropertyType instance = new PropertyType(); +80 instance.setValue("simple"); +81 assertTrue(instance.matches(text)); +82 instance.setCaseSensitive(true); +83 assertFalse(instance.matches(text)); +84 +85 instance.setValue("s.*le"); +86 instance.setRegex(true); +87 assertFalse(instance.matches(text)); +88 instance.setCaseSensitive(false); +89 assertTrue(instance.matches(text)); +90 } +91 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.html index 2089d8a73..06f60ec56 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.html @@ -47,70 +47,51 @@ 39 * 40 * @author Jeremy Long 41 */ -42 public class SuppressionHandlerTest { +42 public class SuppressionHandlerTest extends BaseTest { 43 -44 public SuppressionHandlerTest() { -45 } -46 -47 @BeforeClass -48 public static void setUpClass() { -49 } -50 -51 @AfterClass -52 public static void tearDownClass() { -53 } -54 -55 @Before -56 public void setUp() { -57 } -58 -59 @After -60 public void tearDown() { -61 } -62 -63 /** -64 * Test of getSuppressionRules method, of class SuppressionHandler. -65 * -66 * @throws Exception thrown if there is an exception.... -67 */ -68 @Test -69 public void testHandler() throws Exception { -70 //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); -71 File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); +44 /** +45 * Test of getSuppressionRules method, of class SuppressionHandler. +46 * +47 * @throws Exception thrown if there is an exception.... +48 */ +49 @Test +50 public void testHandler() throws Exception { +51 //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); +52 File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); +53 +54 //File schema = new File(this.getClass().getClassLoader().getResource("schema/suppression.xsd").getPath()); +55 File schema = BaseTest.getResourceAsFile(this, "schema/suppression.xsd"); +56 SuppressionHandler handler = new SuppressionHandler(); +57 +58 SAXParserFactory factory = SAXParserFactory.newInstance(); +59 factory.setNamespaceAware(true); +60 factory.setValidating(true); +61 SAXParser saxParser = factory.newSAXParser(); +62 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); +63 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, schema); +64 XMLReader xmlReader = saxParser.getXMLReader(); +65 xmlReader.setErrorHandler(new SuppressionErrorHandler()); +66 xmlReader.setContentHandler(handler); +67 +68 InputStream inputStream = new FileInputStream(file); +69 Reader reader = new InputStreamReader(inputStream, "UTF-8"); +70 InputSource in = new InputSource(reader); +71 //in.setEncoding("UTF-8"); 72 -73 //File schema = new File(this.getClass().getClassLoader().getResource("schema/suppression.xsd").getPath()); -74 File schema = BaseTest.getResourceAsFile(this, "schema/suppression.xsd"); -75 SuppressionHandler handler = new SuppressionHandler(); -76 -77 SAXParserFactory factory = SAXParserFactory.newInstance(); -78 factory.setNamespaceAware(true); -79 factory.setValidating(true); -80 SAXParser saxParser = factory.newSAXParser(); -81 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); -82 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, schema); -83 XMLReader xmlReader = saxParser.getXMLReader(); -84 xmlReader.setErrorHandler(new SuppressionErrorHandler()); -85 xmlReader.setContentHandler(handler); -86 -87 InputStream inputStream = new FileInputStream(file); -88 Reader reader = new InputStreamReader(inputStream, "UTF-8"); -89 InputSource in = new InputSource(reader); -90 //in.setEncoding("UTF-8"); -91 -92 xmlReader.parse(in); -93 -94 List<SuppressionRule> result = handler.getSuppressionRules(); -95 assertTrue(result.size() > 3); -96 int baseCount = 0; -97 for (SuppressionRule r : result) { -98 if (r.isBase()) { -99 baseCount++; -100 } -101 } -102 assertTrue(baseCount > 0); -103 -104 } -105 } +73 xmlReader.parse(in); +74 +75 List<SuppressionRule> result = handler.getSuppressionRules(); +76 assertTrue(result.size() > 3); +77 int baseCount = 0; +78 for (SuppressionRule r : result) { +79 if (r.isBase()) { +80 baseCount++; +81 } +82 } +83 assertTrue(baseCount > 0); +84 +85 } +86 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionParserTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionParserTest.html index 6e9743f85..c4baf4178 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionParserTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionParserTest.html @@ -40,39 +40,20 @@ 32 * 33 * @author Jeremy Long 34 */ -35 public class SuppressionParserTest { +35 public class SuppressionParserTest extends BaseTest { 36 -37 public SuppressionParserTest() { -38 } -39 -40 @BeforeClass -41 public static void setUpClass() { -42 } -43 -44 @AfterClass -45 public static void tearDownClass() { -46 } -47 -48 @Before -49 public void setUp() { -50 } -51 -52 @After -53 public void tearDown() { -54 } -55 -56 /** -57 * Test of parseSuppressionRules method, of class SuppressionParser. -58 */ -59 @Test -60 public void testParseSuppressionRules() throws Exception { -61 //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); -62 File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); -63 SuppressionParser instance = new SuppressionParser(); -64 List<SuppressionRule> result = instance.parseSuppressionRules(file); -65 assertTrue(result.size() > 3); -66 } -67 } +37 /** +38 * Test of parseSuppressionRules method, of class SuppressionParser. +39 */ +40 @Test +41 public void testParseSuppressionRules() throws Exception { +42 //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); +43 File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); +44 SuppressionParser instance = new SuppressionParser(); +45 List<SuppressionRule> result = instance.parseSuppressionRules(file); +46 assertTrue(result.size() > 3); +47 } +48 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionRuleTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionRuleTest.html index 55e7d1959..c7d9dc4b7 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionRuleTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/SuppressionRuleTest.html @@ -42,7 +42,7 @@ 34 * 35 * @author Jeremy Long 36 */ -37 public class SuppressionRuleTest { +37 public class SuppressionRuleTest extends BaseTest { 38 39 //<editor-fold defaultstate="collapsed" desc="Stupid tests of properties"> 40 /** diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/package-frame.html index ce886c354..a3948efa3 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.suppression diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/package-summary.html index 7a4b3e8c6..e28393679 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/suppression/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.suppression diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html index b8f4b8aff..998326f28 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html @@ -30,53 +30,35 @@ 22 import org.junit.Before; 23 import org.junit.BeforeClass; 24 import org.junit.Test; -25 -26 /** -27 * -28 * @author Jeremy Long -29 */ -30 public class DateUtilTest { -31 -32 public DateUtilTest() { -33 } -34 -35 @BeforeClass -36 public static void setUpClass() { -37 } -38 -39 @AfterClass -40 public static void tearDownClass() { -41 } -42 -43 @Before -44 public void setUp() { -45 } +25 import org.owasp.dependencycheck.BaseTest; +26 +27 /** +28 * +29 * @author Jeremy Long +30 */ +31 public class DateUtilTest extends BaseTest { +32 +33 /** +34 * Test of withinDateRange method, of class DateUtil. +35 */ +36 @Test +37 public void testWithinDateRange() { +38 Calendar c = Calendar.getInstance(); +39 +40 long current = c.getTimeInMillis(); +41 long lastRun = c.getTimeInMillis() - (3 * (1000 * 60 * 60 * 24)); +42 int range = 7; // 7 days +43 boolean expResult = true; +44 boolean result = DateUtil.withinDateRange(lastRun, current, range); +45 assertEquals(expResult, result); 46 -47 @After -48 public void tearDown() { -49 } -50 -51 /** -52 * Test of withinDateRange method, of class DateUtil. -53 */ -54 @Test -55 public void testWithinDateRange() { -56 Calendar c = Calendar.getInstance(); -57 -58 long current = c.getTimeInMillis(); -59 long lastRun = c.getTimeInMillis() - (3 * (1000 * 60 * 60 * 24)); -60 int range = 7; // 7 days -61 boolean expResult = true; -62 boolean result = DateUtil.withinDateRange(lastRun, current, range); -63 assertEquals(expResult, result); -64 -65 lastRun = c.getTimeInMillis() - (8 * (1000 * 60 * 60 * 24)); -66 expResult = false; -67 result = DateUtil.withinDateRange(lastRun, current, range); -68 assertEquals(expResult, result); -69 } -70 -71 } +47 lastRun = c.getTimeInMillis() - (8 * (1000 * 60 * 60 * 24)); +48 expResult = false; +49 result = DateUtil.withinDateRange(lastRun, current, range); +50 assertEquals(expResult, result); +51 } +52 +53 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionTest.html index 8edf796ee..931321b6a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionTest.html @@ -32,179 +32,180 @@ 24 import static org.junit.Assert.assertEquals; 25 import static org.junit.Assert.assertTrue; 26 import org.junit.Test; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class DependencyVersionTest { -33 -34 /** -35 * Test of parseVersion method, of class DependencyVersion. -36 */ -37 @Test -38 public void testParseVersion() { -39 String version = "1.2r1"; -40 DependencyVersion instance = new DependencyVersion(); -41 instance.parseVersion(version); -42 List<String> parts = instance.getVersionParts(); -43 assertEquals(3, parts.size()); -44 assertEquals("1", parts.get(0)); -45 assertEquals("2", parts.get(1)); -46 assertEquals("r1", parts.get(2)); -47 -48 instance.parseVersion("x6.0"); -49 parts = instance.getVersionParts(); -50 assertEquals(2, parts.size()); -51 assertEquals("x6", parts.get(0)); -52 assertEquals("0", parts.get(1)); -53 // TODO(code review): should this be here/do something? -54 //assertEquals("0", parts.get(2)); -55 -56 } -57 -58 /** -59 * Test of iterator method, of class DependencyVersion. -60 */ -61 @Test -62 public void testIterator() { -63 DependencyVersion instance = new DependencyVersion("1.2.3"); -64 Iterator<String> result = instance.iterator(); -65 assertTrue(result.hasNext()); -66 int count = 1; -67 while (result.hasNext()) { -68 String v = result.next(); -69 assertTrue(String.valueOf(count++).equals(v)); -70 } -71 } -72 -73 /** -74 * Test of toString method, of class DependencyVersion. -75 */ -76 @Test -77 public void testToString() { -78 DependencyVersion instance = new DependencyVersion("1.2.3r1"); -79 String expResult = "1.2.3.r1"; -80 String result = instance.toString(); -81 assertEquals(expResult, result); -82 } -83 -84 /** -85 * Test of equals method, of class DependencyVersion. -86 */ -87 @Test -88 public void testEquals() { -89 DependencyVersion obj = new DependencyVersion("1.2.3.r1"); -90 DependencyVersion instance = new DependencyVersion("1.2.3"); -91 boolean expResult = false; -92 boolean result = instance.equals(obj); -93 assertEquals(expResult, result); -94 obj = new DependencyVersion("1.2.3"); -95 expResult = true; -96 result = instance.equals(obj); -97 assertEquals(expResult, result); -98 } -99 -100 /** -101 * Test of hashCode method, of class DependencyVersion. -102 */ -103 @Test -104 public void testHashCode() { -105 DependencyVersion instance = new DependencyVersion("3.2.1"); -106 int expResult = 80756; -107 int result = instance.hashCode(); -108 assertEquals(expResult, result); -109 } -110 -111 /** -112 * Test of matchesAtLeastThreeLevels method, of class DependencyVersion. -113 */ -114 @Test -115 public void testMatchesAtLeastThreeLevels() { -116 -117 DependencyVersion instance = new DependencyVersion("2.3.16.3"); -118 DependencyVersion version = new DependencyVersion("2.3.16.4"); -119 //true tests -120 assertEquals(true, instance.matchesAtLeastThreeLevels(version)); -121 version = new DependencyVersion("2.3"); -122 assertEquals(true, instance.matchesAtLeastThreeLevels(version)); -123 //false tests -124 version = new DependencyVersion("2.3.16.1"); -125 assertEquals(false, instance.matchesAtLeastThreeLevels(version)); -126 version = new DependencyVersion("2"); -127 assertEquals(false, instance.matchesAtLeastThreeLevels(version)); -128 } -129 -130 /** -131 * Test of compareTo method, of class DependencyVersion. -132 */ -133 @Test -134 public void testCompareTo() { -135 DependencyVersion instance = new DependencyVersion("1.2.3"); -136 DependencyVersion version = new DependencyVersion("1.2.3"); -137 assertEquals(0, instance.compareTo(version)); -138 version = new DependencyVersion("1.1"); -139 assertEquals(1, instance.compareTo(version)); -140 version = new DependencyVersion("1.2"); -141 assertEquals(1, instance.compareTo(version)); -142 version = new DependencyVersion("1.3"); -143 assertEquals(-1, instance.compareTo(version)); -144 version = new DependencyVersion("1.2.3.1"); -145 assertEquals(-1, instance.compareTo(version)); -146 -147 instance = new DependencyVersion("1.0.1n"); -148 version = new DependencyVersion("1.0.1m"); -149 assertEquals(1, instance.compareTo(version)); -150 version = new DependencyVersion("1.0.1n"); -151 assertEquals(0, instance.compareTo(version)); -152 version = new DependencyVersion("1.0.1o"); -153 assertEquals(-1, instance.compareTo(version)); -154 -155 DependencyVersion[] dv = new DependencyVersion[7]; -156 dv[0] = new DependencyVersion("2.1.3"); -157 dv[1] = new DependencyVersion("2.1.3.r2"); -158 dv[2] = new DependencyVersion("2.1.3.r1"); -159 dv[3] = new DependencyVersion("1.2.3.1"); -160 dv[4] = new DependencyVersion("1.2.3"); -161 dv[5] = new DependencyVersion("2"); -162 dv[6] = new DependencyVersion("-"); -163 -164 DependencyVersion[] expected = new DependencyVersion[7]; -165 expected[0] = new DependencyVersion("-"); -166 expected[1] = new DependencyVersion("1.2.3"); -167 expected[2] = new DependencyVersion("1.2.3.1"); -168 expected[3] = new DependencyVersion("2"); -169 expected[4] = new DependencyVersion("2.1.3"); -170 expected[5] = new DependencyVersion("2.1.3.r1"); -171 expected[6] = new DependencyVersion("2.1.3.r2"); -172 java.util.Arrays.sort(dv); -173 -174 assertArrayEquals(expected, dv); -175 } -176 -177 /** -178 * Test of getVersionParts method, of class DependencyVersion. -179 */ -180 @Test -181 public void testGetVersionParts() { -182 DependencyVersion instance = new DependencyVersion(); -183 List<String> versionParts = Arrays.asList("1", "1", "1"); -184 instance.setVersionParts(versionParts); -185 List<String> expResult = Arrays.asList("1", "1", "1"); -186 List<String> result = instance.getVersionParts(); -187 assertEquals(expResult, result); -188 } -189 -190 /** -191 * Test of setVersionParts method, of class DependencyVersion. -192 */ -193 @Test -194 public void testSetVersionParts() { -195 List<String> versionParts = Arrays.asList("1", "1", "1"); -196 DependencyVersion instance = new DependencyVersion(); -197 instance.setVersionParts(versionParts); -198 } -199 } +27 import org.owasp.dependencycheck.BaseTest; +28 +29 /** +30 * +31 * @author Jeremy Long +32 */ +33 public class DependencyVersionTest extends BaseTest { +34 +35 /** +36 * Test of parseVersion method, of class DependencyVersion. +37 */ +38 @Test +39 public void testParseVersion() { +40 String version = "1.2r1"; +41 DependencyVersion instance = new DependencyVersion(); +42 instance.parseVersion(version); +43 List<String> parts = instance.getVersionParts(); +44 assertEquals(3, parts.size()); +45 assertEquals("1", parts.get(0)); +46 assertEquals("2", parts.get(1)); +47 assertEquals("r1", parts.get(2)); +48 +49 instance.parseVersion("x6.0"); +50 parts = instance.getVersionParts(); +51 assertEquals(2, parts.size()); +52 assertEquals("x6", parts.get(0)); +53 assertEquals("0", parts.get(1)); +54 // TODO(code review): should this be here/do something? +55 //assertEquals("0", parts.get(2)); +56 +57 } +58 +59 /** +60 * Test of iterator method, of class DependencyVersion. +61 */ +62 @Test +63 public void testIterator() { +64 DependencyVersion instance = new DependencyVersion("1.2.3"); +65 Iterator<String> result = instance.iterator(); +66 assertTrue(result.hasNext()); +67 int count = 1; +68 while (result.hasNext()) { +69 String v = result.next(); +70 assertTrue(String.valueOf(count++).equals(v)); +71 } +72 } +73 +74 /** +75 * Test of toString method, of class DependencyVersion. +76 */ +77 @Test +78 public void testToString() { +79 DependencyVersion instance = new DependencyVersion("1.2.3r1"); +80 String expResult = "1.2.3.r1"; +81 String result = instance.toString(); +82 assertEquals(expResult, result); +83 } +84 +85 /** +86 * Test of equals method, of class DependencyVersion. +87 */ +88 @Test +89 public void testEquals() { +90 DependencyVersion obj = new DependencyVersion("1.2.3.r1"); +91 DependencyVersion instance = new DependencyVersion("1.2.3"); +92 boolean expResult = false; +93 boolean result = instance.equals(obj); +94 assertEquals(expResult, result); +95 obj = new DependencyVersion("1.2.3"); +96 expResult = true; +97 result = instance.equals(obj); +98 assertEquals(expResult, result); +99 } +100 +101 /** +102 * Test of hashCode method, of class DependencyVersion. +103 */ +104 @Test +105 public void testHashCode() { +106 DependencyVersion instance = new DependencyVersion("3.2.1"); +107 int expResult = 80756; +108 int result = instance.hashCode(); +109 assertEquals(expResult, result); +110 } +111 +112 /** +113 * Test of matchesAtLeastThreeLevels method, of class DependencyVersion. +114 */ +115 @Test +116 public void testMatchesAtLeastThreeLevels() { +117 +118 DependencyVersion instance = new DependencyVersion("2.3.16.3"); +119 DependencyVersion version = new DependencyVersion("2.3.16.4"); +120 //true tests +121 assertEquals(true, instance.matchesAtLeastThreeLevels(version)); +122 version = new DependencyVersion("2.3"); +123 assertEquals(true, instance.matchesAtLeastThreeLevels(version)); +124 //false tests +125 version = new DependencyVersion("2.3.16.1"); +126 assertEquals(false, instance.matchesAtLeastThreeLevels(version)); +127 version = new DependencyVersion("2"); +128 assertEquals(false, instance.matchesAtLeastThreeLevels(version)); +129 } +130 +131 /** +132 * Test of compareTo method, of class DependencyVersion. +133 */ +134 @Test +135 public void testCompareTo() { +136 DependencyVersion instance = new DependencyVersion("1.2.3"); +137 DependencyVersion version = new DependencyVersion("1.2.3"); +138 assertEquals(0, instance.compareTo(version)); +139 version = new DependencyVersion("1.1"); +140 assertEquals(1, instance.compareTo(version)); +141 version = new DependencyVersion("1.2"); +142 assertEquals(1, instance.compareTo(version)); +143 version = new DependencyVersion("1.3"); +144 assertEquals(-1, instance.compareTo(version)); +145 version = new DependencyVersion("1.2.3.1"); +146 assertEquals(-1, instance.compareTo(version)); +147 +148 instance = new DependencyVersion("1.0.1n"); +149 version = new DependencyVersion("1.0.1m"); +150 assertEquals(1, instance.compareTo(version)); +151 version = new DependencyVersion("1.0.1n"); +152 assertEquals(0, instance.compareTo(version)); +153 version = new DependencyVersion("1.0.1o"); +154 assertEquals(-1, instance.compareTo(version)); +155 +156 DependencyVersion[] dv = new DependencyVersion[7]; +157 dv[0] = new DependencyVersion("2.1.3"); +158 dv[1] = new DependencyVersion("2.1.3.r2"); +159 dv[2] = new DependencyVersion("2.1.3.r1"); +160 dv[3] = new DependencyVersion("1.2.3.1"); +161 dv[4] = new DependencyVersion("1.2.3"); +162 dv[5] = new DependencyVersion("2"); +163 dv[6] = new DependencyVersion("-"); +164 +165 DependencyVersion[] expected = new DependencyVersion[7]; +166 expected[0] = new DependencyVersion("-"); +167 expected[1] = new DependencyVersion("1.2.3"); +168 expected[2] = new DependencyVersion("1.2.3.1"); +169 expected[3] = new DependencyVersion("2"); +170 expected[4] = new DependencyVersion("2.1.3"); +171 expected[5] = new DependencyVersion("2.1.3.r1"); +172 expected[6] = new DependencyVersion("2.1.3.r2"); +173 java.util.Arrays.sort(dv); +174 +175 assertArrayEquals(expected, dv); +176 } +177 +178 /** +179 * Test of getVersionParts method, of class DependencyVersion. +180 */ +181 @Test +182 public void testGetVersionParts() { +183 DependencyVersion instance = new DependencyVersion(); +184 List<String> versionParts = Arrays.asList("1", "1", "1"); +185 instance.setVersionParts(versionParts); +186 List<String> expResult = Arrays.asList("1", "1", "1"); +187 List<String> result = instance.getVersionParts(); +188 assertEquals(expResult, result); +189 } +190 +191 /** +192 * Test of setVersionParts method, of class DependencyVersion. +193 */ +194 @Test +195 public void testSetVersionParts() { +196 List<String> versionParts = Arrays.asList("1", "1", "1"); +197 DependencyVersion instance = new DependencyVersion(); +198 instance.setVersionParts(versionParts); +199 } +200 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html index 085e4e6a1..9bcab3e6d 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html @@ -32,63 +32,45 @@ 24 import org.junit.Before; 25 import org.junit.BeforeClass; 26 import org.junit.Test; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class DependencyVersionUtilTest { -33 -34 public DependencyVersionUtilTest() { -35 } -36 -37 @BeforeClass -38 public static void setUpClass() throws Exception { -39 } -40 -41 @AfterClass -42 public static void tearDownClass() throws Exception { -43 } -44 -45 @Before -46 public void setUp() { -47 } +27 import org.owasp.dependencycheck.BaseTest; +28 +29 /** +30 * +31 * @author Jeremy Long +32 */ +33 public class DependencyVersionUtilTest extends BaseTest { +34 +35 /** +36 * Test of parseVersion method, of class DependencyVersionUtil. +37 */ +38 @Test +39 public void testParseVersion() { +40 final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar", +41 "lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar", +42 "lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar", +43 "-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar", +44 "plone.rfc822-1.1.1-py2-none-any.whl"}; +45 final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1", +46 "2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", +47 "2.2.8.02", "1.1.1"}; 48 -49 @After -50 public void tearDown() { -51 } -52 -53 /** -54 * Test of parseVersion method, of class DependencyVersionUtil. -55 */ -56 @Test -57 public void testParseVersion() { -58 final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar", -59 "lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar", -60 "lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar", -61 "-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar", -62 "plone.rfc822-1.1.1-py2-none-any.whl"}; -63 final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1", -64 "2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", -65 "2.2.8.02", "1.1.1"}; -66 -67 for (int i = 0; i < fileName.length; i++) { -68 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]); -69 String result = null; -70 if (version != null) { -71 result = version.toString(); -72 } -73 assertEquals("Failed extraction on \"" + fileName[i] + "\".", expResult[i], result); -74 } -75 -76 String[] failingNames = {"no-version-identified.jar", "somelib-04aug2000r7-dev.jar", /*"no.version15.jar",*/ -77 "lib_1.0_spec-1.1.jar", "lib-api_1.0_spec-1.0.1.jar"}; -78 for (String failingName : failingNames) { -79 final DependencyVersion version = DependencyVersionUtil.parseVersion(failingName); -80 assertNull("Found version in name that should have failed \"" + failingName + "\".", version); -81 } -82 } -83 } +49 for (int i = 0; i < fileName.length; i++) { +50 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]); +51 String result = null; +52 if (version != null) { +53 result = version.toString(); +54 } +55 assertEquals("Failed extraction on \"" + fileName[i] + "\".", expResult[i], result); +56 } +57 +58 String[] failingNames = {"no-version-identified.jar", "somelib-04aug2000r7-dev.jar", /*"no.version15.jar",*/ +59 "lib_1.0_spec-1.1.jar", "lib-api_1.0_spec-1.0.1.jar"}; +60 for (String failingName : failingNames) { +61 final DependencyVersion version = DependencyVersionUtil.parseVersion(failingName); +62 assertNull("Found version in name that should have failed \"" + failingName + "\".", version); +63 } +64 } +65 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/FilterTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/FilterTest.html index be16a51a8..64052cd26 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/FilterTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/FilterTest.html @@ -31,53 +31,54 @@ 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertTrue; 25 import org.junit.Test; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class FilterTest { -32 -33 /** -34 * Test of passes method, of class Filter. -35 */ -36 @Test -37 public void testPasses() { -38 String keep = "keep"; -39 String fail = "fail"; -40 -41 assertTrue("String contained keep - but passes returned false.", TEST_FILTER.passes(keep)); -42 assertFalse("String contained fail - but passes returned true.", TEST_FILTER.passes(fail)); -43 } -44 -45 /** -46 * Test of filter method, of class Filter. -47 */ -48 @Test -49 public void testFilter_Iterable() { -50 List<String> testData = new ArrayList<String>(); -51 testData.add("keep"); -52 testData.add("remove"); -53 testData.add("keep"); -54 -55 List<String> expResults = new ArrayList<String>(); -56 expResults.add("keep"); +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public class FilterTest extends BaseTest { +33 +34 /** +35 * Test of passes method, of class Filter. +36 */ +37 @Test +38 public void testPasses() { +39 String keep = "keep"; +40 String fail = "fail"; +41 +42 assertTrue("String contained keep - but passes returned false.", TEST_FILTER.passes(keep)); +43 assertFalse("String contained fail - but passes returned true.", TEST_FILTER.passes(fail)); +44 } +45 +46 /** +47 * Test of filter method, of class Filter. +48 */ +49 @Test +50 public void testFilter_Iterable() { +51 List<String> testData = new ArrayList<String>(); +52 testData.add("keep"); +53 testData.add("remove"); +54 testData.add("keep"); +55 +56 List<String> expResults = new ArrayList<String>(); 57 expResults.add("keep"); -58 -59 List<String> actResults = new ArrayList<String>(); -60 for (String s : TEST_FILTER.filter(testData)) { -61 actResults.add(s); -62 } -63 assertArrayEquals(expResults.toArray(), actResults.toArray()); -64 } -65 private static final Filter<String> TEST_FILTER -66 = new Filter<String>() { -67 @Override -68 public boolean passes(String str) { -69 return str.contains("keep"); -70 } -71 }; -72 } +58 expResults.add("keep"); +59 +60 List<String> actResults = new ArrayList<String>(); +61 for (String s : TEST_FILTER.filter(testData)) { +62 actResults.add(s); +63 } +64 assertArrayEquals(expResults.toArray(), actResults.toArray()); +65 } +66 private static final Filter<String> TEST_FILTER +67 = new Filter<String>() { +68 @Override +69 public boolean passes(String str) { +70 return str.contains("keep"); +71 } +72 }; +73 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-frame.html index a1ed0106c..95b2d0da8 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-summary.html index 4785ceaca..e9278ec91 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/ModelTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/ModelTest.html index f623c2f59..a53f4d292 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/ModelTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/ModelTest.html @@ -31,266 +31,267 @@ 23 24 import org.junit.Test; 25 import static org.junit.Assert.*; -26 -27 /** -28 * -29 * @author jeremy -30 */ -31 public class ModelTest { -32 -33 /** -34 * Test of getName method, of class Model. -35 */ -36 @Test -37 public void testGetName() { -38 Model instance = new Model(); -39 instance.setName(""); -40 String expResult = ""; -41 String result = instance.getName(); -42 assertEquals(expResult, result); -43 } -44 -45 /** -46 * Test of setName method, of class Model. -47 */ -48 @Test -49 public void testSetName() { -50 String name = ""; -51 Model instance = new Model(); -52 instance.setName(name); -53 } -54 -55 /** -56 * Test of getOrganization method, of class Model. -57 */ -58 @Test -59 public void testGetOrganization() { -60 Model instance = new Model(); -61 instance.setOrganization(""); -62 String expResult = ""; -63 String result = instance.getOrganization(); -64 assertEquals(expResult, result); -65 } -66 -67 /** -68 * Test of setOrganization method, of class Model. -69 */ -70 @Test -71 public void testSetOrganization() { -72 String organization = ""; -73 Model instance = new Model(); -74 instance.setOrganization(organization); -75 } -76 -77 /** -78 * Test of getDescription method, of class Model. -79 */ -80 @Test -81 public void testGetDescription() { -82 Model instance = new Model(); -83 instance.setDescription(""); -84 String expResult = ""; -85 String result = instance.getDescription(); -86 assertEquals(expResult, result); -87 } -88 -89 /** -90 * Test of setDescription method, of class Model. -91 */ -92 @Test -93 public void testSetDescription() { -94 String description = ""; -95 Model instance = new Model(); -96 instance.setDescription(description); -97 } -98 -99 /** -100 * Test of getGroupId method, of class Model. -101 */ -102 @Test -103 public void testGetGroupId() { -104 Model instance = new Model(); -105 instance.setGroupId(""); -106 String expResult = ""; -107 String result = instance.getGroupId(); -108 assertEquals(expResult, result); -109 } -110 -111 /** -112 * Test of setGroupId method, of class Model. -113 */ -114 @Test -115 public void testSetGroupId() { -116 String groupId = ""; -117 Model instance = new Model(); -118 instance.setGroupId(groupId); -119 } -120 -121 /** -122 * Test of getArtifactId method, of class Model. -123 */ -124 @Test -125 public void testGetArtifactId() { -126 Model instance = new Model(); -127 instance.setArtifactId(""); -128 String expResult = ""; -129 String result = instance.getArtifactId(); -130 assertEquals(expResult, result); -131 } -132 -133 /** -134 * Test of setArtifactId method, of class Model. -135 */ -136 @Test -137 public void testSetArtifactId() { -138 String artifactId = ""; -139 Model instance = new Model(); -140 instance.setArtifactId(artifactId); -141 } -142 -143 /** -144 * Test of getVersion method, of class Model. -145 */ -146 @Test -147 public void testGetVersion() { -148 Model instance = new Model(); -149 instance.setVersion(""); -150 String expResult = ""; -151 String result = instance.getVersion(); -152 assertEquals(expResult, result); -153 } -154 -155 /** -156 * Test of setVersion method, of class Model. -157 */ -158 @Test -159 public void testSetVersion() { -160 String version = ""; -161 Model instance = new Model(); -162 instance.setVersion(version); -163 } -164 -165 /** -166 * Test of getParentGroupId method, of class Model. -167 */ -168 @Test -169 public void testGetParentGroupId() { -170 Model instance = new Model(); -171 instance.setParentGroupId(""); -172 String expResult = ""; -173 String result = instance.getParentGroupId(); -174 assertEquals(expResult, result); -175 } -176 -177 /** -178 * Test of setParentGroupId method, of class Model. -179 */ -180 @Test -181 public void testSetParentGroupId() { -182 String parentGroupId = ""; -183 Model instance = new Model(); -184 instance.setParentGroupId(parentGroupId); -185 } -186 -187 /** -188 * Test of getParentArtifactId method, of class Model. -189 */ -190 @Test -191 public void testGetParentArtifactId() { -192 Model instance = new Model(); -193 instance.setParentArtifactId(""); -194 String expResult = ""; -195 String result = instance.getParentArtifactId(); -196 assertEquals(expResult, result); -197 } -198 -199 /** -200 * Test of setParentArtifactId method, of class Model. -201 */ -202 @Test -203 public void testSetParentArtifactId() { -204 String parentArtifactId = ""; -205 Model instance = new Model(); -206 instance.setParentArtifactId(parentArtifactId); -207 } -208 -209 /** -210 * Test of getParentVersion method, of class Model. -211 */ -212 @Test -213 public void testGetParentVersion() { -214 Model instance = new Model(); -215 instance.setParentVersion(""); -216 String expResult = ""; -217 String result = instance.getParentVersion(); -218 assertEquals(expResult, result); -219 } -220 -221 /** -222 * Test of setParentVersion method, of class Model. -223 */ -224 @Test -225 public void testSetParentVersion() { -226 String parentVersion = ""; -227 Model instance = new Model(); -228 instance.setParentVersion(parentVersion); -229 } -230 -231 /** -232 * Test of getLicenses method, of class Model. -233 */ -234 @Test -235 public void testGetLicenses() { -236 Model instance = new Model(); -237 instance.addLicense(new License("name", "url")); -238 List<License> expResult = new ArrayList<License>(); -239 expResult.add(new License("name", "url")); -240 List<License> result = instance.getLicenses(); -241 assertEquals(expResult, result); -242 } -243 -244 /** -245 * Test of addLicense method, of class Model. -246 */ -247 @Test -248 public void testAddLicense() { -249 License license = new License("name", "url"); -250 Model instance = new Model(); -251 instance.addLicense(license); -252 } -253 -254 /** -255 * Test of processProperties method, of class Model. -256 */ -257 @Test -258 public void testProcessProperties() { -259 Properties prop = new Properties(); -260 prop.setProperty("key", "value"); -261 prop.setProperty("nested", "nested ${key}"); -262 String text = "This is a test of '${key}' '${nested}'"; -263 -264 Model instance = new Model(); -265 instance.setName(text); -266 instance.processProperties(prop); -267 String expResults = "This is a test of 'value' 'nested value'"; -268 assertEquals(expResults, instance.getName()); -269 } -270 -271 /** -272 * Test of interpolateString method, of class Model. -273 */ -274 @Test -275 public void testInterpolateString() { -276 Properties prop = new Properties(); -277 prop.setProperty("key", "value"); -278 prop.setProperty("nested", "nested ${key}"); -279 String text = "This is a test of '${key}' '${nested}'"; -280 String expResults = "This is a test of 'value' 'nested value'"; -281 String results = Model.interpolateString(text, prop); -282 assertEquals(expResults, results); -283 } -284 -285 } +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author jeremy +31 */ +32 public class ModelTest extends BaseTest { +33 +34 /** +35 * Test of getName method, of class Model. +36 */ +37 @Test +38 public void testGetName() { +39 Model instance = new Model(); +40 instance.setName(""); +41 String expResult = ""; +42 String result = instance.getName(); +43 assertEquals(expResult, result); +44 } +45 +46 /** +47 * Test of setName method, of class Model. +48 */ +49 @Test +50 public void testSetName() { +51 String name = ""; +52 Model instance = new Model(); +53 instance.setName(name); +54 } +55 +56 /** +57 * Test of getOrganization method, of class Model. +58 */ +59 @Test +60 public void testGetOrganization() { +61 Model instance = new Model(); +62 instance.setOrganization(""); +63 String expResult = ""; +64 String result = instance.getOrganization(); +65 assertEquals(expResult, result); +66 } +67 +68 /** +69 * Test of setOrganization method, of class Model. +70 */ +71 @Test +72 public void testSetOrganization() { +73 String organization = ""; +74 Model instance = new Model(); +75 instance.setOrganization(organization); +76 } +77 +78 /** +79 * Test of getDescription method, of class Model. +80 */ +81 @Test +82 public void testGetDescription() { +83 Model instance = new Model(); +84 instance.setDescription(""); +85 String expResult = ""; +86 String result = instance.getDescription(); +87 assertEquals(expResult, result); +88 } +89 +90 /** +91 * Test of setDescription method, of class Model. +92 */ +93 @Test +94 public void testSetDescription() { +95 String description = ""; +96 Model instance = new Model(); +97 instance.setDescription(description); +98 } +99 +100 /** +101 * Test of getGroupId method, of class Model. +102 */ +103 @Test +104 public void testGetGroupId() { +105 Model instance = new Model(); +106 instance.setGroupId(""); +107 String expResult = ""; +108 String result = instance.getGroupId(); +109 assertEquals(expResult, result); +110 } +111 +112 /** +113 * Test of setGroupId method, of class Model. +114 */ +115 @Test +116 public void testSetGroupId() { +117 String groupId = ""; +118 Model instance = new Model(); +119 instance.setGroupId(groupId); +120 } +121 +122 /** +123 * Test of getArtifactId method, of class Model. +124 */ +125 @Test +126 public void testGetArtifactId() { +127 Model instance = new Model(); +128 instance.setArtifactId(""); +129 String expResult = ""; +130 String result = instance.getArtifactId(); +131 assertEquals(expResult, result); +132 } +133 +134 /** +135 * Test of setArtifactId method, of class Model. +136 */ +137 @Test +138 public void testSetArtifactId() { +139 String artifactId = ""; +140 Model instance = new Model(); +141 instance.setArtifactId(artifactId); +142 } +143 +144 /** +145 * Test of getVersion method, of class Model. +146 */ +147 @Test +148 public void testGetVersion() { +149 Model instance = new Model(); +150 instance.setVersion(""); +151 String expResult = ""; +152 String result = instance.getVersion(); +153 assertEquals(expResult, result); +154 } +155 +156 /** +157 * Test of setVersion method, of class Model. +158 */ +159 @Test +160 public void testSetVersion() { +161 String version = ""; +162 Model instance = new Model(); +163 instance.setVersion(version); +164 } +165 +166 /** +167 * Test of getParentGroupId method, of class Model. +168 */ +169 @Test +170 public void testGetParentGroupId() { +171 Model instance = new Model(); +172 instance.setParentGroupId(""); +173 String expResult = ""; +174 String result = instance.getParentGroupId(); +175 assertEquals(expResult, result); +176 } +177 +178 /** +179 * Test of setParentGroupId method, of class Model. +180 */ +181 @Test +182 public void testSetParentGroupId() { +183 String parentGroupId = ""; +184 Model instance = new Model(); +185 instance.setParentGroupId(parentGroupId); +186 } +187 +188 /** +189 * Test of getParentArtifactId method, of class Model. +190 */ +191 @Test +192 public void testGetParentArtifactId() { +193 Model instance = new Model(); +194 instance.setParentArtifactId(""); +195 String expResult = ""; +196 String result = instance.getParentArtifactId(); +197 assertEquals(expResult, result); +198 } +199 +200 /** +201 * Test of setParentArtifactId method, of class Model. +202 */ +203 @Test +204 public void testSetParentArtifactId() { +205 String parentArtifactId = ""; +206 Model instance = new Model(); +207 instance.setParentArtifactId(parentArtifactId); +208 } +209 +210 /** +211 * Test of getParentVersion method, of class Model. +212 */ +213 @Test +214 public void testGetParentVersion() { +215 Model instance = new Model(); +216 instance.setParentVersion(""); +217 String expResult = ""; +218 String result = instance.getParentVersion(); +219 assertEquals(expResult, result); +220 } +221 +222 /** +223 * Test of setParentVersion method, of class Model. +224 */ +225 @Test +226 public void testSetParentVersion() { +227 String parentVersion = ""; +228 Model instance = new Model(); +229 instance.setParentVersion(parentVersion); +230 } +231 +232 /** +233 * Test of getLicenses method, of class Model. +234 */ +235 @Test +236 public void testGetLicenses() { +237 Model instance = new Model(); +238 instance.addLicense(new License("name", "url")); +239 List<License> expResult = new ArrayList<License>(); +240 expResult.add(new License("name", "url")); +241 List<License> result = instance.getLicenses(); +242 assertEquals(expResult, result); +243 } +244 +245 /** +246 * Test of addLicense method, of class Model. +247 */ +248 @Test +249 public void testAddLicense() { +250 License license = new License("name", "url"); +251 Model instance = new Model(); +252 instance.addLicense(license); +253 } +254 +255 /** +256 * Test of processProperties method, of class Model. +257 */ +258 @Test +259 public void testProcessProperties() { +260 Properties prop = new Properties(); +261 prop.setProperty("key", "value"); +262 prop.setProperty("nested", "nested ${key}"); +263 String text = "This is a test of '${key}' '${nested}'"; +264 +265 Model instance = new Model(); +266 instance.setName(text); +267 instance.processProperties(prop); +268 String expResults = "This is a test of 'value' 'nested value'"; +269 assertEquals(expResults, instance.getName()); +270 } +271 +272 /** +273 * Test of interpolateString method, of class Model. +274 */ +275 @Test +276 public void testInterpolateString() { +277 Properties prop = new Properties(); +278 prop.setProperty("key", "value"); +279 prop.setProperty("nested", "nested ${key}"); +280 String text = "This is a test of '${key}' '${nested}'"; +281 String expResults = "This is a test of 'value' 'nested value'"; +282 String results = Model.interpolateString(text, prop); +283 assertEquals(expResults, results); +284 } +285 +286 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/PomUtilsTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/PomUtilsTest.html index e7b16a7ec..ee3723757 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/PomUtilsTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/PomUtilsTest.html @@ -35,7 +35,7 @@ 27 * 28 * @author jeremy 29 */ -30 public class PomUtilsTest { +30 public class PomUtilsTest extends BaseTest { 31 32 /** 33 * Test of readPom method, of class PomUtils. diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html index 52929518d..b011975e2 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html index 65f206207..aaba3714e 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/dependency-check-core/xref-test/overview-frame.html b/dependency-check-core/xref-test/overview-frame.html index f29080b74..35225aabb 100644 --- a/dependency-check-core/xref-test/overview-frame.html +++ b/dependency-check-core/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference + Dependency-Check Core 1.4.0 Reference diff --git a/dependency-check-core/xref-test/overview-summary.html b/dependency-check-core/xref-test/overview-summary.html index 1a5deb8a0..1d6874ae8 100644 --- a/dependency-check-core/xref-test/overview-summary.html +++ b/dependency-check-core/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference + Dependency-Check Core 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Core 1.3.6 Reference

      +

      Dependency-Check Core 1.4.0 Reference

      diff --git a/dependency-check-core/xref/allclasses-frame.html b/dependency-check-core/xref/allclasses-frame.html index 47331c821..e5ebac828 100644 --- a/dependency-check-core/xref/allclasses-frame.html +++ b/dependency-check-core/xref/allclasses-frame.html @@ -175,6 +175,9 @@
    66. EvidenceCollection +
    67. +
    68. + Experimental
    69. ExtractionUtil @@ -322,6 +325,9 @@
    70. RubyBundleAuditAnalyzer +
    71. +
    72. + RubyBundlerAnalyzer
    73. RubyGemspecAnalyzer diff --git a/dependency-check-core/xref/index.html b/dependency-check-core/xref/index.html index bb6a4037a..e71e8ba73 100644 --- a/dependency-check-core/xref/index.html +++ b/dependency-check-core/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Core 1.3.6 Reference + Dependency-Check Core 1.4.0 Reference diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html b/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html index e0d2c869a..e8916237e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html @@ -134,383 +134,382 @@ 126 } 127 128 final AnalyzerService service = new AnalyzerService(serviceClassLoader); -129 final Iterator<Analyzer> iterator = service.getAnalyzers(); -130 while (iterator.hasNext()) { -131 final Analyzer a = iterator.next(); -132 analyzers.get(a.getAnalysisPhase()).add(a); -133 if (a instanceof FileTypeAnalyzer) { -134 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); -135 } -136 } -137 } -138 -139 /** -140 * Get the List of the analyzers for a specific phase of analysis. -141 * -142 * @param phase the phase to get the configured analyzers. -143 * @return the analyzers loaded -144 */ -145 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { -146 return analyzers.get(phase); -147 } -148 -149 /** -150 * Get the dependencies identified. -151 * -152 * @return the dependencies identified -153 */ -154 public List<Dependency> getDependencies() { -155 return dependencies; -156 } -157 -158 /** -159 * Sets the dependencies. -160 * -161 * @param dependencies the dependencies -162 */ -163 public void setDependencies(List<Dependency> dependencies) { -164 this.dependencies = dependencies; -165 } -166 -167 /** -168 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -169 * identified are added to the dependency collection. -170 * -171 * @param paths an array of paths to files or directories to be analyzed -172 * @return the list of dependencies scanned -173 * @since v0.3.2.5 -174 */ -175 public List<Dependency> scan(String[] paths) { -176 final List<Dependency> deps = new ArrayList<Dependency>(); -177 for (String path : paths) { -178 final List<Dependency> d = scan(path); -179 if (d != null) { -180 deps.addAll(d); -181 } -182 } -183 return deps; -184 } -185 -186 /** -187 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified -188 * are added to the dependency collection. -189 * -190 * @param path the path to a file or directory to be analyzed -191 * @return the list of dependencies scanned -192 */ -193 public List<Dependency> scan(String path) { -194 final File file = new File(path); -195 return scan(file); -196 } -197 -198 /** -199 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -200 * identified are added to the dependency collection. -201 * -202 * @param files an array of paths to files or directories to be analyzed. -203 * @return the list of dependencies -204 * @since v0.3.2.5 -205 */ -206 public List<Dependency> scan(File[] files) { -207 final List<Dependency> deps = new ArrayList<Dependency>(); -208 for (File file : files) { -209 final List<Dependency> d = scan(file); -210 if (d != null) { -211 deps.addAll(d); -212 } -213 } -214 return deps; -215 } -216 -217 /** -218 * Scans a collection of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -219 * identified are added to the dependency collection. -220 * -221 * @param files a set of paths to files or directories to be analyzed -222 * @return the list of dependencies scanned -223 * @since v0.3.2.5 -224 */ -225 public List<Dependency> scan(Collection<File> files) { -226 final List<Dependency> deps = new ArrayList<Dependency>(); -227 for (File file : files) { -228 final List<Dependency> d = scan(file); -229 if (d != null) { -230 deps.addAll(d); -231 } -232 } -233 return deps; -234 } -235 -236 /** -237 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified -238 * are added to the dependency collection. -239 * -240 * @param file the path to a file or directory to be analyzed -241 * @return the list of dependencies scanned -242 * @since v0.3.2.4 -243 */ -244 public List<Dependency> scan(File file) { -245 if (file.exists()) { -246 if (file.isDirectory()) { -247 return scanDirectory(file); -248 } else { -249 final Dependency d = scanFile(file); -250 if (d != null) { -251 final List<Dependency> deps = new ArrayList<Dependency>(); -252 deps.add(d); -253 return deps; -254 } -255 } -256 } -257 return null; -258 } -259 -260 /** -261 * Recursively scans files and directories. Any dependencies identified are added to the dependency collection. -262 * -263 * @param dir the directory to scan -264 * @return the list of Dependency objects scanned -265 */ -266 protected List<Dependency> scanDirectory(File dir) { -267 final File[] files = dir.listFiles(); -268 final List<Dependency> deps = new ArrayList<Dependency>(); -269 if (files != null) { -270 for (File f : files) { -271 if (f.isDirectory()) { -272 final List<Dependency> d = scanDirectory(f); -273 if (d != null) { -274 deps.addAll(d); -275 } -276 } else { -277 final Dependency d = scanFile(f); -278 deps.add(d); -279 } -280 } -281 } -282 return deps; -283 } -284 -285 /** -286 * Scans a specified file. If a dependency is identified it is added to the dependency collection. -287 * -288 * @param file The file to scan -289 * @return the scanned dependency -290 */ -291 protected Dependency scanFile(File file) { -292 Dependency dependency = null; -293 if (file.isFile()) { -294 if (accept(file)) { -295 dependency = new Dependency(file); -296 dependencies.add(dependency); -297 } -298 } else { -299 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file); -300 } -301 return dependency; -302 } -303 -304 /** -305 * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via -306 * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for -307 * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the -308 * dependencies list. -309 */ -310 public void analyzeDependencies() { -311 boolean autoUpdate = true; -312 try { -313 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -314 } catch (InvalidSettingException ex) { -315 LOGGER.debug("Invalid setting for auto-update; using true."); -316 } -317 if (autoUpdate) { -318 doUpdates(); -319 } -320 -321 //need to ensure that data exists -322 try { -323 ensureDataExists(); -324 } catch (NoDataException ex) { -325 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); -326 LOGGER.debug("", ex); -327 return; -328 } catch (DatabaseException ex) { -329 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); -330 LOGGER.debug("", ex); -331 return; -332 -333 } -334 -335 LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); -336 LOGGER.info("Analysis Starting"); -337 final long analysisStart = System.currentTimeMillis(); -338 -339 // analysis phases -340 for (AnalysisPhase phase : AnalysisPhase.values()) { -341 final List<Analyzer> analyzerList = analyzers.get(phase); -342 -343 for (Analyzer a : analyzerList) { -344 a = initializeAnalyzer(a); -345 -346 /* need to create a copy of the collection because some of the -347 * analyzers may modify it. This prevents ConcurrentModificationExceptions. -348 * This is okay for adds/deletes because it happens per analyzer. -349 */ -350 LOGGER.debug("Begin Analyzer '{}'", a.getName()); -351 final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies); -352 for (Dependency d : dependencySet) { -353 boolean shouldAnalyze = true; -354 if (a instanceof FileTypeAnalyzer) { -355 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; -356 shouldAnalyze = fAnalyzer.accept(d.getActualFile()); -357 } -358 if (shouldAnalyze) { -359 LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath()); -360 try { -361 a.analyze(d, this); -362 } catch (AnalysisException ex) { -363 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath()); -364 LOGGER.debug("", ex); -365 } catch (Throwable ex) { -366 //final AnalysisException ax = new AnalysisException(axMsg, ex); -367 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath()); -368 LOGGER.debug("", ex); -369 } -370 } -371 } -372 } -373 } -374 for (AnalysisPhase phase : AnalysisPhase.values()) { -375 final List<Analyzer> analyzerList = analyzers.get(phase); -376 -377 for (Analyzer a : analyzerList) { -378 closeAnalyzer(a); -379 } -380 } -381 -382 LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); -383 LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart); -384 } -385 -386 /** -387 * Initializes the given analyzer. -388 * -389 * @param analyzer the analyzer to initialize -390 * @return the initialized analyzer -391 */ -392 protected Analyzer initializeAnalyzer(Analyzer analyzer) { -393 try { -394 LOGGER.debug("Initializing {}", analyzer.getName()); -395 analyzer.initialize(); -396 } catch (Throwable ex) { -397 LOGGER.error("Exception occurred initializing {}.", analyzer.getName()); -398 LOGGER.debug("", ex); -399 try { -400 analyzer.close(); -401 } catch (Throwable ex1) { -402 LOGGER.trace("", ex1); -403 } -404 } -405 return analyzer; -406 } -407 -408 /** -409 * Closes the given analyzer. -410 * -411 * @param analyzer the analyzer to close -412 */ -413 protected void closeAnalyzer(Analyzer analyzer) { -414 LOGGER.debug("Closing Analyzer '{}'", analyzer.getName()); -415 try { -416 analyzer.close(); -417 } catch (Throwable ex) { -418 LOGGER.trace("", ex); -419 } -420 } -421 -422 /** -423 * Cycles through the cached web data sources and calls update on all of them. -424 */ -425 public void doUpdates() { -426 LOGGER.info("Checking for updates"); -427 final long updateStart = System.currentTimeMillis(); -428 final UpdateService service = new UpdateService(serviceClassLoader); -429 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); -430 while (iterator.hasNext()) { -431 final CachedWebDataSource source = iterator.next(); -432 try { -433 source.update(); -434 } catch (UpdateException ex) { -435 LOGGER.warn( -436 "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities."); -437 LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex); -438 } -439 } -440 LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); -441 } -442 -443 /** -444 * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used. -445 * -446 * @return a list of Analyzers -447 */ -448 public List<Analyzer> getAnalyzers() { -449 final List<Analyzer> ret = new ArrayList<Analyzer>(); -450 for (AnalysisPhase phase : AnalysisPhase.values()) { -451 final List<Analyzer> analyzerList = analyzers.get(phase); -452 ret.addAll(analyzerList); -453 } -454 return ret; -455 } -456 -457 /** -458 * Checks all analyzers to see if an extension is supported. -459 * -460 * @param file a file extension -461 * @return true or false depending on whether or not the file extension is supported -462 */ -463 @Override -464 public boolean accept(File file) { -465 if (file == null) { -466 return false; -467 } -468 boolean scan = false; -469 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { -470 /* note, we can't break early on this loop as the analyzers need to know if -471 they have files to work on prior to initialization */ -472 scan |= a.accept(file); -473 } -474 return scan; -475 } -476 -477 /** -478 * Returns the set of file type analyzers. -479 * -480 * @return the set of file type analyzers -481 */ -482 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { -483 return this.fileTypeAnalyzers; -484 } -485 -486 /** -487 * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown. -488 * -489 * @throws NoDataException thrown if no data exists in the CPE Index -490 * @throws DatabaseException thrown if there is an exception opening the database -491 */ -492 private void ensureDataExists() throws NoDataException, DatabaseException { -493 final CveDB cve = new CveDB(); -494 try { -495 cve.open(); -496 if (!cve.dataExists()) { -497 throw new NoDataException("No documents exist"); -498 } -499 } catch (DatabaseException ex) { -500 throw new NoDataException(ex.getMessage(), ex); -501 } finally { -502 cve.close(); -503 } -504 } -505 } +129 final List<Analyzer> iterator = service.getAnalyzers(); +130 for (Analyzer a : iterator) { +131 analyzers.get(a.getAnalysisPhase()).add(a); +132 if (a instanceof FileTypeAnalyzer) { +133 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); +134 } +135 } +136 } +137 +138 /** +139 * Get the List of the analyzers for a specific phase of analysis. +140 * +141 * @param phase the phase to get the configured analyzers. +142 * @return the analyzers loaded +143 */ +144 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { +145 return analyzers.get(phase); +146 } +147 +148 /** +149 * Get the dependencies identified. +150 * +151 * @return the dependencies identified +152 */ +153 public List<Dependency> getDependencies() { +154 return dependencies; +155 } +156 +157 /** +158 * Sets the dependencies. +159 * +160 * @param dependencies the dependencies +161 */ +162 public void setDependencies(List<Dependency> dependencies) { +163 this.dependencies = dependencies; +164 } +165 +166 /** +167 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies +168 * identified are added to the dependency collection. +169 * +170 * @param paths an array of paths to files or directories to be analyzed +171 * @return the list of dependencies scanned +172 * @since v0.3.2.5 +173 */ +174 public List<Dependency> scan(String[] paths) { +175 final List<Dependency> deps = new ArrayList<Dependency>(); +176 for (String path : paths) { +177 final List<Dependency> d = scan(path); +178 if (d != null) { +179 deps.addAll(d); +180 } +181 } +182 return deps; +183 } +184 +185 /** +186 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified +187 * are added to the dependency collection. +188 * +189 * @param path the path to a file or directory to be analyzed +190 * @return the list of dependencies scanned +191 */ +192 public List<Dependency> scan(String path) { +193 final File file = new File(path); +194 return scan(file); +195 } +196 +197 /** +198 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies +199 * identified are added to the dependency collection. +200 * +201 * @param files an array of paths to files or directories to be analyzed. +202 * @return the list of dependencies +203 * @since v0.3.2.5 +204 */ +205 public List<Dependency> scan(File[] files) { +206 final List<Dependency> deps = new ArrayList<Dependency>(); +207 for (File file : files) { +208 final List<Dependency> d = scan(file); +209 if (d != null) { +210 deps.addAll(d); +211 } +212 } +213 return deps; +214 } +215 +216 /** +217 * Scans a collection of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies +218 * identified are added to the dependency collection. +219 * +220 * @param files a set of paths to files or directories to be analyzed +221 * @return the list of dependencies scanned +222 * @since v0.3.2.5 +223 */ +224 public List<Dependency> scan(Collection<File> files) { +225 final List<Dependency> deps = new ArrayList<Dependency>(); +226 for (File file : files) { +227 final List<Dependency> d = scan(file); +228 if (d != null) { +229 deps.addAll(d); +230 } +231 } +232 return deps; +233 } +234 +235 /** +236 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified +237 * are added to the dependency collection. +238 * +239 * @param file the path to a file or directory to be analyzed +240 * @return the list of dependencies scanned +241 * @since v0.3.2.4 +242 */ +243 public List<Dependency> scan(File file) { +244 if (file.exists()) { +245 if (file.isDirectory()) { +246 return scanDirectory(file); +247 } else { +248 final Dependency d = scanFile(file); +249 if (d != null) { +250 final List<Dependency> deps = new ArrayList<Dependency>(); +251 deps.add(d); +252 return deps; +253 } +254 } +255 } +256 return null; +257 } +258 +259 /** +260 * Recursively scans files and directories. Any dependencies identified are added to the dependency collection. +261 * +262 * @param dir the directory to scan +263 * @return the list of Dependency objects scanned +264 */ +265 protected List<Dependency> scanDirectory(File dir) { +266 final File[] files = dir.listFiles(); +267 final List<Dependency> deps = new ArrayList<Dependency>(); +268 if (files != null) { +269 for (File f : files) { +270 if (f.isDirectory()) { +271 final List<Dependency> d = scanDirectory(f); +272 if (d != null) { +273 deps.addAll(d); +274 } +275 } else { +276 final Dependency d = scanFile(f); +277 deps.add(d); +278 } +279 } +280 } +281 return deps; +282 } +283 +284 /** +285 * Scans a specified file. If a dependency is identified it is added to the dependency collection. +286 * +287 * @param file The file to scan +288 * @return the scanned dependency +289 */ +290 protected Dependency scanFile(File file) { +291 Dependency dependency = null; +292 if (file.isFile()) { +293 if (accept(file)) { +294 dependency = new Dependency(file); +295 dependencies.add(dependency); +296 } +297 } else { +298 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file); +299 } +300 return dependency; +301 } +302 +303 /** +304 * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via +305 * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for +306 * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the +307 * dependencies list. +308 */ +309 public void analyzeDependencies() { +310 boolean autoUpdate = true; +311 try { +312 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +313 } catch (InvalidSettingException ex) { +314 LOGGER.debug("Invalid setting for auto-update; using true."); +315 } +316 if (autoUpdate) { +317 doUpdates(); +318 } +319 +320 //need to ensure that data exists +321 try { +322 ensureDataExists(); +323 } catch (NoDataException ex) { +324 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +325 LOGGER.debug("", ex); +326 return; +327 } catch (DatabaseException ex) { +328 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +329 LOGGER.debug("", ex); +330 return; +331 +332 } +333 +334 LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); +335 LOGGER.info("Analysis Starting"); +336 final long analysisStart = System.currentTimeMillis(); +337 +338 // analysis phases +339 for (AnalysisPhase phase : AnalysisPhase.values()) { +340 final List<Analyzer> analyzerList = analyzers.get(phase); +341 +342 for (Analyzer a : analyzerList) { +343 a = initializeAnalyzer(a); +344 +345 /* need to create a copy of the collection because some of the +346 * analyzers may modify it. This prevents ConcurrentModificationExceptions. +347 * This is okay for adds/deletes because it happens per analyzer. +348 */ +349 LOGGER.debug("Begin Analyzer '{}'", a.getName()); +350 final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies); +351 for (Dependency d : dependencySet) { +352 boolean shouldAnalyze = true; +353 if (a instanceof FileTypeAnalyzer) { +354 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; +355 shouldAnalyze = fAnalyzer.accept(d.getActualFile()); +356 } +357 if (shouldAnalyze) { +358 LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath()); +359 try { +360 a.analyze(d, this); +361 } catch (AnalysisException ex) { +362 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath()); +363 LOGGER.debug("", ex); +364 } catch (Throwable ex) { +365 //final AnalysisException ax = new AnalysisException(axMsg, ex); +366 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath()); +367 LOGGER.debug("", ex); +368 } +369 } +370 } +371 } +372 } +373 for (AnalysisPhase phase : AnalysisPhase.values()) { +374 final List<Analyzer> analyzerList = analyzers.get(phase); +375 +376 for (Analyzer a : analyzerList) { +377 closeAnalyzer(a); +378 } +379 } +380 +381 LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); +382 LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart); +383 } +384 +385 /** +386 * Initializes the given analyzer. +387 * +388 * @param analyzer the analyzer to initialize +389 * @return the initialized analyzer +390 */ +391 protected Analyzer initializeAnalyzer(Analyzer analyzer) { +392 try { +393 LOGGER.debug("Initializing {}", analyzer.getName()); +394 analyzer.initialize(); +395 } catch (Throwable ex) { +396 LOGGER.error("Exception occurred initializing {}.", analyzer.getName()); +397 LOGGER.debug("", ex); +398 try { +399 analyzer.close(); +400 } catch (Throwable ex1) { +401 LOGGER.trace("", ex1); +402 } +403 } +404 return analyzer; +405 } +406 +407 /** +408 * Closes the given analyzer. +409 * +410 * @param analyzer the analyzer to close +411 */ +412 protected void closeAnalyzer(Analyzer analyzer) { +413 LOGGER.debug("Closing Analyzer '{}'", analyzer.getName()); +414 try { +415 analyzer.close(); +416 } catch (Throwable ex) { +417 LOGGER.trace("", ex); +418 } +419 } +420 +421 /** +422 * Cycles through the cached web data sources and calls update on all of them. +423 */ +424 public void doUpdates() { +425 LOGGER.info("Checking for updates"); +426 final long updateStart = System.currentTimeMillis(); +427 final UpdateService service = new UpdateService(serviceClassLoader); +428 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); +429 while (iterator.hasNext()) { +430 final CachedWebDataSource source = iterator.next(); +431 try { +432 source.update(); +433 } catch (UpdateException ex) { +434 LOGGER.warn( +435 "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities."); +436 LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex); +437 } +438 } +439 LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); +440 } +441 +442 /** +443 * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used. +444 * +445 * @return a list of Analyzers +446 */ +447 public List<Analyzer> getAnalyzers() { +448 final List<Analyzer> ret = new ArrayList<Analyzer>(); +449 for (AnalysisPhase phase : AnalysisPhase.values()) { +450 final List<Analyzer> analyzerList = analyzers.get(phase); +451 ret.addAll(analyzerList); +452 } +453 return ret; +454 } +455 +456 /** +457 * Checks all analyzers to see if an extension is supported. +458 * +459 * @param file a file extension +460 * @return true or false depending on whether or not the file extension is supported +461 */ +462 @Override +463 public boolean accept(File file) { +464 if (file == null) { +465 return false; +466 } +467 boolean scan = false; +468 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { +469 /* note, we can't break early on this loop as the analyzers need to know if +470 they have files to work on prior to initialization */ +471 scan |= a.accept(file); +472 } +473 return scan; +474 } +475 +476 /** +477 * Returns the set of file type analyzers. +478 * +479 * @return the set of file type analyzers +480 */ +481 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { +482 return this.fileTypeAnalyzers; +483 } +484 +485 /** +486 * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown. +487 * +488 * @throws NoDataException thrown if no data exists in the CPE Index +489 * @throws DatabaseException thrown if there is an exception opening the database +490 */ +491 private void ensureDataExists() throws NoDataException, DatabaseException { +492 final CveDB cve = new CveDB(); +493 try { +494 cve.open(); +495 if (!cve.dataExists()) { +496 throw new NoDataException("No documents exist"); +497 } +498 } catch (DatabaseException ex) { +499 throw new NoDataException(ex.getMessage(), ex); +500 } finally { +501 cve.close(); +502 } +503 } +504 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-frame.html index 1cfb5be0d..8a6447bc9 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.agent + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.agent diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-summary.html index a39b3e89c..8084e6d6e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.agent + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.agent diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html index b692366ac..974fddd8b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html @@ -42,147 +42,154 @@ 34 import org.owasp.dependencycheck.utils.Settings; 35 import org.slf4j.Logger; 36 import org.slf4j.LoggerFactory; -37 -38 /** -39 * Abstract base suppression analyzer that contains methods for parsing the suppression xml file. -40 * -41 * @author Jeremy Long -42 */ -43 public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { -44 -45 /** -46 * The Logger for use throughout the class -47 */ -48 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class); -49 -50 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -51 /** -52 * Returns a list of file EXTENSIONS supported by this analyzer. -53 * -54 * @return a list of file EXTENSIONS supported by this analyzer. -55 */ -56 public Set<String> getSupportedExtensions() { -57 return null; -58 } -59 -60 //</editor-fold> -61 /** -62 * The initialize method loads the suppression XML file. -63 * -64 * @throws Exception thrown if there is an exception -65 */ -66 @Override -67 public void initialize() throws Exception { -68 super.initialize(); -69 loadSuppressionData(); -70 } -71 -72 /** -73 * The list of suppression rules -74 */ -75 private List<SuppressionRule> rules; -76 -77 /** -78 * Get the value of rules. -79 * -80 * @return the value of rules -81 */ -82 public List<SuppressionRule> getRules() { -83 return rules; -84 } -85 -86 /** -87 * Set the value of rules. -88 * -89 * @param rules new value of rules -90 */ -91 public void setRules(List<SuppressionRule> rules) { -92 this.rules = rules; -93 } -94 -95 /** -96 * Loads the suppression rules file. -97 * -98 * @throws SuppressionParseException thrown if the XML cannot be parsed. -99 */ -100 private void loadSuppressionData() throws SuppressionParseException { -101 final SuppressionParser parser = new SuppressionParser(); -102 File file = null; -103 try { -104 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); -105 } catch (SuppressionParseException ex) { -106 LOGGER.debug("Unable to parse the base suppression data file", ex); -107 } -108 final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); -109 if (suppressionFilePath == null) { -110 return; -111 } -112 boolean deleteTempFile = false; -113 try { -114 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); -115 if (uriRx.matcher(suppressionFilePath).matches()) { -116 deleteTempFile = true; -117 file = FileUtils.getTempFile("suppression", "xml"); -118 final URL url = new URL(suppressionFilePath); -119 try { -120 Downloader.fetchFile(url, file, false); -121 } catch (DownloadFailedException ex) { -122 Downloader.fetchFile(url, file, true); -123 } -124 } else { -125 file = new File(suppressionFilePath); -126 if (!file.exists()) { -127 final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); -128 if (suppressionsFromClasspath != null) { -129 deleteTempFile = true; -130 file = FileUtils.getTempFile("suppression", "xml"); -131 try { -132 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); -133 } catch (IOException ex) { -134 throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); -135 } -136 } -137 } -138 } -139 -140 if (file != null) { -141 try { -142 //rules = parser.parseSuppressionRules(file); -143 rules.addAll(parser.parseSuppressionRules(file)); -144 LOGGER.debug("{} suppression rules were loaded.", rules.size()); -145 } catch (SuppressionParseException ex) { -146 LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); -147 LOGGER.warn(ex.getMessage()); -148 LOGGER.debug("", ex); -149 throw ex; -150 } -151 } -152 } catch (DownloadFailedException ex) { -153 throwSuppressionParseException("Unable to fetch the configured suppression file", ex); -154 } catch (MalformedURLException ex) { -155 throwSuppressionParseException("Configured suppression file has an invalid URL", ex); -156 } catch (IOException ex) { -157 throwSuppressionParseException("Unable to create temp file for suppressions", ex); -158 } finally { -159 if (deleteTempFile && file != null) { -160 FileUtils.delete(file); -161 } -162 } -163 } -164 -165 /** -166 * Utility method to throw parse exceptions. -167 * -168 * @param message the exception message -169 * @param exception the cause of the exception -170 * @throws SuppressionParseException throws the generated SuppressionParseException -171 */ -172 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { -173 LOGGER.warn(message); -174 LOGGER.debug("", exception); -175 throw new SuppressionParseException(message, exception); -176 } -177 } +37 import org.xml.sax.SAXException; +38 +39 /** +40 * Abstract base suppression analyzer that contains methods for parsing the +41 * suppression xml file. +42 * +43 * @author Jeremy Long +44 */ +45 public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { +46 +47 /** +48 * The Logger for use throughout the class +49 */ +50 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class); +51 +52 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +53 /** +54 * Returns a list of file EXTENSIONS supported by this analyzer. +55 * +56 * @return a list of file EXTENSIONS supported by this analyzer. +57 */ +58 public Set<String> getSupportedExtensions() { +59 return null; +60 } +61 +62 //</editor-fold> +63 /** +64 * The initialize method loads the suppression XML file. +65 * +66 * @throws Exception thrown if there is an exception +67 */ +68 @Override +69 public void initialize() throws Exception { +70 super.initialize(); +71 loadSuppressionData(); +72 } +73 +74 /** +75 * The list of suppression rules +76 */ +77 private List<SuppressionRule> rules; +78 +79 /** +80 * Get the value of rules. +81 * +82 * @return the value of rules +83 */ +84 public List<SuppressionRule> getRules() { +85 return rules; +86 } +87 +88 /** +89 * Set the value of rules. +90 * +91 * @param rules new value of rules +92 */ +93 public void setRules(List<SuppressionRule> rules) { +94 this.rules = rules; +95 } +96 +97 /** +98 * Loads the suppression rules file. +99 * +100 * @throws SuppressionParseException thrown if the XML cannot be parsed. +101 */ +102 private void loadSuppressionData() throws SuppressionParseException { +103 final SuppressionParser parser = new SuppressionParser(); +104 File file = null; +105 try { +106 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); +107 } catch (SuppressionParseException ex) { +108 LOGGER.error("Unable to parse the base suppression data file"); +109 LOGGER.debug("Unable to parse the base suppression data file", ex); +110 } catch (SAXException ex) { +111 LOGGER.error("Unable to parse the base suppression data file"); +112 LOGGER.debug("Unable to parse the base suppression data file", ex); +113 } +114 final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); +115 if (suppressionFilePath == null) { +116 return; +117 } +118 boolean deleteTempFile = false; +119 try { +120 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); +121 if (uriRx.matcher(suppressionFilePath).matches()) { +122 deleteTempFile = true; +123 file = FileUtils.getTempFile("suppression", "xml"); +124 final URL url = new URL(suppressionFilePath); +125 try { +126 Downloader.fetchFile(url, file, false); +127 } catch (DownloadFailedException ex) { +128 Downloader.fetchFile(url, file, true); +129 } +130 } else { +131 file = new File(suppressionFilePath); +132 if (!file.exists()) { +133 final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); +134 if (suppressionsFromClasspath != null) { +135 deleteTempFile = true; +136 file = FileUtils.getTempFile("suppression", "xml"); +137 try { +138 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); +139 } catch (IOException ex) { +140 throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); +141 } +142 } +143 } +144 } +145 +146 if (file != null) { +147 try { +148 //rules = parser.parseSuppressionRules(file); +149 rules.addAll(parser.parseSuppressionRules(file)); +150 LOGGER.debug("{} suppression rules were loaded.", rules.size()); +151 } catch (SuppressionParseException ex) { +152 LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); +153 LOGGER.warn(ex.getMessage()); +154 LOGGER.debug("", ex); +155 throw ex; +156 } +157 } +158 } catch (DownloadFailedException ex) { +159 throwSuppressionParseException("Unable to fetch the configured suppression file", ex); +160 } catch (MalformedURLException ex) { +161 throwSuppressionParseException("Configured suppression file has an invalid URL", ex); +162 } catch (IOException ex) { +163 throwSuppressionParseException("Unable to create temp file for suppressions", ex); +164 } finally { +165 if (deleteTempFile && file != null) { +166 FileUtils.delete(file); +167 } +168 } +169 } +170 +171 /** +172 * Utility method to throw parse exceptions. +173 * +174 * @param message the exception message +175 * @param exception the cause of the exception +176 * @throws SuppressionParseException throws the generated +177 * SuppressionParseException +178 */ +179 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { +180 LOGGER.warn(message); +181 LOGGER.debug("", exception); +182 throw new SuppressionParseException(message, exception); +183 } +184 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AnalyzerService.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AnalyzerService.html index 2c7cc2f90..05caba69a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AnalyzerService.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AnalyzerService.html @@ -25,40 +25,65 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.util.Iterator; -21 import java.util.ServiceLoader; -22 -23 /** -24 * The Analyzer Service Loader. This class loads all services that implement -25 * org.owasp.dependencycheck.analyzer.Analyzer. -26 * -27 * @author Jeremy Long -28 */ -29 public class AnalyzerService { -30 -31 /** -32 * The service loader for analyzers. -33 */ -34 private final ServiceLoader<Analyzer> loader; -35 -36 /** -37 * Creates a new instance of AnalyzerService. -38 * -39 * @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services -40 */ -41 public AnalyzerService(ClassLoader classLoader) { -42 loader = ServiceLoader.load(Analyzer.class, classLoader); -43 } +20 import java.util.ArrayList; +21 import java.util.Iterator; +22 import java.util.List; +23 import java.util.ServiceLoader; +24 import org.owasp.dependencycheck.utils.InvalidSettingException; +25 import org.owasp.dependencycheck.utils.Settings; +26 import org.slf4j.LoggerFactory; +27 +28 /** +29 * The Analyzer Service Loader. This class loads all services that implement +30 * org.owasp.dependencycheck.analyzer.Analyzer. +31 * +32 * @author Jeremy Long +33 */ +34 public class AnalyzerService { +35 /** +36 * The Logger for use throughout the class. +37 */ +38 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnalyzerService.class); +39 +40 /** +41 * The service loader for analyzers. +42 */ +43 private final ServiceLoader<Analyzer> service; 44 45 /** -46 * Returns an Iterator for all instances of the Analyzer interface. +46 * Creates a new instance of AnalyzerService. 47 * -48 * @return an iterator of Analyzers. +48 * @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services 49 */ -50 public Iterator<Analyzer> getAnalyzers() { -51 return loader.iterator(); +50 public AnalyzerService(ClassLoader classLoader) { +51 service = ServiceLoader.load(Analyzer.class, classLoader); 52 } -53 } +53 +54 /** +55 * Returns a list of all instances of the Analyzer interface. +56 * +57 * @return a list of Analyzers. +58 */ +59 public List<Analyzer> getAnalyzers() { +60 final List<Analyzer> analyzers = new ArrayList<Analyzer>(); +61 final Iterator<Analyzer> iterator = service.iterator(); +62 boolean experimentalEnabled = false; +63 try { +64 experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); +65 } catch (InvalidSettingException ex) { +66 LOGGER.error("invalide experimental setting", ex); +67 } +68 while (iterator.hasNext()) { +69 final Analyzer a = iterator.next(); +70 if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) { +71 continue; +72 } +73 LOGGER.debug("Loaded Analyzer {}", a.getName()); +74 analyzers.add(a); +75 } +76 return analyzers; +77 } +78 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html index 2410e0932..7561a4627 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html @@ -38,204 +38,204 @@ 30 import java.io.File; 31 import java.io.FileFilter; 32 import java.io.IOException; -33 import java.util.ArrayList; -34 import java.util.List; -35 import java.util.regex.Matcher; -36 import java.util.regex.Pattern; -37 -38 /** -39 * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed, -40 * assuming they are generated by Autoconf, and contain certain special package descriptor variables. -41 * -42 * @author Dale Visser -43 * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a> -44 */ -45 public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { -46 -47 /** -48 * Autoconf output filename. -49 */ -50 private static final String CONFIGURE = "configure"; -51 -52 /** -53 * Autoconf input filename. -54 */ -55 private static final String CONFIGURE_IN = "configure.in"; -56 -57 /** -58 * Autoconf input filename. -59 */ -60 private static final String CONFIGURE_AC = "configure.ac"; -61 -62 /** -63 * The name of the analyzer. -64 */ -65 private static final String ANALYZER_NAME = "Autoconf Analyzer"; -66 -67 /** -68 * The phase that this analyzer is intended to run in. -69 */ -70 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -71 -72 /** -73 * The set of file extensions supported by this analyzer. -74 */ -75 private static final String[] EXTENSIONS = {"ac", "in"}; -76 -77 /** -78 * Matches AC_INIT variables in the output configure script. -79 */ -80 private static final Pattern PACKAGE_VAR = Pattern.compile( -81 "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); -82 -83 /** -84 * Matches AC_INIT statement in configure.ac file. -85 */ -86 private static final Pattern AC_INIT_PATTERN; -87 -88 static { -89 // each instance of param or sep_param has a capture group -90 final String param = "\\[{0,2}(.+?)\\]{0,2}"; -91 final String sepParam = "\\s*,\\s*" + param; -92 // Group 1: Package -93 // Group 2: Version -94 // Group 3: optional -95 // Group 4: Bug report address (if it exists) -96 // Group 5: optional -97 // Group 6: Tarname (if it exists) -98 // Group 7: optional -99 // Group 8: URL (if it exists) -100 AC_INIT_PATTERN = Pattern.compile(String.format( -101 "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam, -102 sepParam, sepParam, sepParam), Pattern.DOTALL -103 | Pattern.CASE_INSENSITIVE); -104 } -105 -106 /** -107 * The file filter used to determine which files this analyzer supports. -108 */ -109 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions( -110 EXTENSIONS).build(); -111 -112 /** -113 * Returns the FileFilter -114 * -115 * @return the FileFilter -116 */ -117 @Override -118 protected FileFilter getFileFilter() { -119 return FILTER; -120 } -121 -122 /** -123 * Returns the name of the analyzer. -124 * -125 * @return the name of the analyzer. -126 */ -127 @Override -128 public String getName() { -129 return ANALYZER_NAME; -130 } -131 -132 /** -133 * Returns the phase that the analyzer is intended to run in. -134 * -135 * @return the phase that the analyzer is intended to run in. -136 */ -137 @Override -138 public AnalysisPhase getAnalysisPhase() { -139 return ANALYSIS_PHASE; -140 } -141 -142 /** -143 * Returns the key used in the properties file to reference the analyzer's enabled property. -144 * -145 * @return the analyzer's enabled property setting key -146 */ -147 @Override -148 protected String getAnalyzerEnabledSettingKey() { -149 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; -150 } -151 -152 @Override -153 protected void analyzeFileType(Dependency dependency, Engine engine) -154 throws AnalysisException { -155 final File actualFile = dependency.getActualFile(); -156 final String name = actualFile.getName(); -157 if (name.startsWith(CONFIGURE)) { -158 final File parent = actualFile.getParentFile(); -159 final String parentName = parent.getName(); -160 dependency.setDisplayFileName(parentName + "/" + name); -161 final boolean isOutputScript = CONFIGURE.equals(name); -162 if (isOutputScript || CONFIGURE_AC.equals(name) -163 || CONFIGURE_IN.equals(name)) { -164 final String contents = getFileContents(actualFile); -165 if (!contents.isEmpty()) { -166 if (isOutputScript) { -167 extractConfigureScriptEvidence(dependency, name, -168 contents); -169 } else { -170 gatherEvidence(dependency, name, contents); -171 } -172 } -173 } -174 } else { -175 // copy, alter and set in case some other thread is iterating over -176 final List<Dependency> dependencies = new ArrayList<Dependency>( -177 engine.getDependencies()); -178 dependencies.remove(dependency); -179 engine.setDependencies(dependencies); -180 } -181 } -182 -183 /** -184 * Extracts evidence from the configuration. -185 * -186 * @param dependency the dependency being analyzed -187 * @param name the name of the source of evidence -188 * @param contents the contents to analyze for evidence -189 */ -190 private void extractConfigureScriptEvidence(Dependency dependency, -191 final String name, final String contents) { -192 final Matcher matcher = PACKAGE_VAR.matcher(contents); -193 while (matcher.find()) { -194 final String variable = matcher.group(1); -195 final String value = matcher.group(2); -196 if (!value.isEmpty()) { -197 if (variable.endsWith("NAME")) { -198 dependency.getProductEvidence().addEvidence(name, variable, -199 value, Confidence.HIGHEST); -200 } else if ("VERSION".equals(variable)) { -201 dependency.getVersionEvidence().addEvidence(name, variable, -202 value, Confidence.HIGHEST); -203 } else if ("BUGREPORT".equals(variable)) { -204 dependency.getVendorEvidence().addEvidence(name, variable, -205 value, Confidence.HIGH); -206 } else if ("URL".equals(variable)) { -207 dependency.getVendorEvidence().addEvidence(name, variable, -208 value, Confidence.HIGH); -209 } -210 } -211 } -212 } -213 -214 /** -215 * Retrieves the contents of a given file. -216 * -217 * @param actualFile the file to read -218 * @return the contents of the file -219 * @throws AnalysisException thrown if there is an IO Exception -220 */ -221 private String getFileContents(final File actualFile) -222 throws AnalysisException { -223 String contents = ""; -224 try { -225 contents = FileUtils.readFileToString(actualFile).trim(); -226 } catch (IOException e) { -227 throw new AnalysisException( -228 "Problem occurred while reading dependency file.", e); -229 } -230 return contents; +33 import java.nio.charset.Charset; +34 import java.util.ArrayList; +35 import java.util.List; +36 import java.util.regex.Matcher; +37 import java.util.regex.Pattern; +38 +39 /** +40 * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed, +41 * assuming they are generated by Autoconf, and contain certain special package descriptor variables. +42 * +43 * @author Dale Visser +44 * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a> +45 */ +46 @Experimental +47 public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { +48 +49 /** +50 * Autoconf output filename. +51 */ +52 private static final String CONFIGURE = "configure"; +53 +54 /** +55 * Autoconf input filename. +56 */ +57 private static final String CONFIGURE_IN = "configure.in"; +58 +59 /** +60 * Autoconf input filename. +61 */ +62 private static final String CONFIGURE_AC = "configure.ac"; +63 +64 /** +65 * The name of the analyzer. +66 */ +67 private static final String ANALYZER_NAME = "Autoconf Analyzer"; +68 +69 /** +70 * The phase that this analyzer is intended to run in. +71 */ +72 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +73 +74 /** +75 * The set of file extensions supported by this analyzer. +76 */ +77 private static final String[] EXTENSIONS = {"ac", "in"}; +78 +79 /** +80 * Matches AC_INIT variables in the output configure script. +81 */ +82 private static final Pattern PACKAGE_VAR = Pattern.compile( +83 "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); +84 +85 /** +86 * Matches AC_INIT statement in configure.ac file. +87 */ +88 private static final Pattern AC_INIT_PATTERN; +89 +90 static { +91 // each instance of param or sep_param has a capture group +92 final String param = "\\[{0,2}(.+?)\\]{0,2}"; +93 final String sepParam = "\\s*,\\s*" + param; +94 // Group 1: Package +95 // Group 2: Version +96 // Group 3: optional +97 // Group 4: Bug report address (if it exists) +98 // Group 5: optional +99 // Group 6: Tarname (if it exists) +100 // Group 7: optional +101 // Group 8: URL (if it exists) +102 AC_INIT_PATTERN = Pattern.compile(String.format( +103 "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam, +104 sepParam, sepParam, sepParam), Pattern.DOTALL +105 | Pattern.CASE_INSENSITIVE); +106 } +107 +108 /** +109 * The file filter used to determine which files this analyzer supports. +110 */ +111 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions( +112 EXTENSIONS).build(); +113 +114 /** +115 * Returns the FileFilter +116 * +117 * @return the FileFilter +118 */ +119 @Override +120 protected FileFilter getFileFilter() { +121 return FILTER; +122 } +123 +124 /** +125 * Returns the name of the analyzer. +126 * +127 * @return the name of the analyzer. +128 */ +129 @Override +130 public String getName() { +131 return ANALYZER_NAME; +132 } +133 +134 /** +135 * Returns the phase that the analyzer is intended to run in. +136 * +137 * @return the phase that the analyzer is intended to run in. +138 */ +139 @Override +140 public AnalysisPhase getAnalysisPhase() { +141 return ANALYSIS_PHASE; +142 } +143 +144 /** +145 * Returns the key used in the properties file to reference the analyzer's enabled property. +146 * +147 * @return the analyzer's enabled property setting key +148 */ +149 @Override +150 protected String getAnalyzerEnabledSettingKey() { +151 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; +152 } +153 +154 @Override +155 protected void analyzeFileType(Dependency dependency, Engine engine) +156 throws AnalysisException { +157 final File actualFile = dependency.getActualFile(); +158 final String name = actualFile.getName(); +159 if (name.startsWith(CONFIGURE)) { +160 final File parent = actualFile.getParentFile(); +161 final String parentName = parent.getName(); +162 dependency.setDisplayFileName(parentName + "/" + name); +163 final boolean isOutputScript = CONFIGURE.equals(name); +164 if (isOutputScript || CONFIGURE_AC.equals(name) +165 || CONFIGURE_IN.equals(name)) { +166 final String contents = getFileContents(actualFile); +167 if (!contents.isEmpty()) { +168 if (isOutputScript) { +169 extractConfigureScriptEvidence(dependency, name, +170 contents); +171 } else { +172 gatherEvidence(dependency, name, contents); +173 } +174 } +175 } +176 } else { +177 // copy, alter and set in case some other thread is iterating over +178 final List<Dependency> dependencies = new ArrayList<Dependency>( +179 engine.getDependencies()); +180 dependencies.remove(dependency); +181 engine.setDependencies(dependencies); +182 } +183 } +184 +185 /** +186 * Extracts evidence from the configuration. +187 * +188 * @param dependency the dependency being analyzed +189 * @param name the name of the source of evidence +190 * @param contents the contents to analyze for evidence +191 */ +192 private void extractConfigureScriptEvidence(Dependency dependency, +193 final String name, final String contents) { +194 final Matcher matcher = PACKAGE_VAR.matcher(contents); +195 while (matcher.find()) { +196 final String variable = matcher.group(1); +197 final String value = matcher.group(2); +198 if (!value.isEmpty()) { +199 if (variable.endsWith("NAME")) { +200 dependency.getProductEvidence().addEvidence(name, variable, +201 value, Confidence.HIGHEST); +202 } else if ("VERSION".equals(variable)) { +203 dependency.getVersionEvidence().addEvidence(name, variable, +204 value, Confidence.HIGHEST); +205 } else if ("BUGREPORT".equals(variable)) { +206 dependency.getVendorEvidence().addEvidence(name, variable, +207 value, Confidence.HIGH); +208 } else if ("URL".equals(variable)) { +209 dependency.getVendorEvidence().addEvidence(name, variable, +210 value, Confidence.HIGH); +211 } +212 } +213 } +214 } +215 +216 /** +217 * Retrieves the contents of a given file. +218 * +219 * @param actualFile the file to read +220 * @return the contents of the file +221 * @throws AnalysisException thrown if there is an IO Exception +222 */ +223 private String getFileContents(final File actualFile) +224 throws AnalysisException { +225 try { +226 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); +227 } catch (IOException e) { +228 throw new AnalysisException( +229 "Problem occurred while reading dependency file.", e); +230 } 231 } 232 233 /** diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html index df6dc23a0..f5f3f1e81 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html @@ -41,208 +41,210 @@ 33 import java.io.FileFilter; 34 import java.io.IOException; 35 import java.io.UnsupportedEncodingException; -36 import java.security.MessageDigest; -37 import java.security.NoSuchAlgorithmException; -38 import java.util.regex.Matcher; -39 import java.util.regex.Pattern; -40 -41 /** -42 * <p> -43 * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p> -44 * <p> -45 * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version -46 * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert -47 * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be -48 * identified.</p> -49 * -50 * @author Dale Visser -51 */ -52 public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { -53 -54 /** -55 * The logger. -56 */ -57 private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class); -58 -59 /** -60 * Used when compiling file scanning regex patterns. -61 */ -62 private static final int REGEX_OPTIONS = Pattern.DOTALL -63 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE; -64 -65 /** -66 * Regex to extract the product information. -67 */ -68 private static final Pattern PROJECT = Pattern.compile( -69 "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS); -70 -71 /** -72 * Regex to extract product and version information. -73 * -74 * Group 1: Product +36 import java.nio.charset.Charset; +37 import java.security.MessageDigest; +38 import java.security.NoSuchAlgorithmException; +39 import java.util.regex.Matcher; +40 import java.util.regex.Pattern; +41 +42 /** +43 * <p> +44 * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p> +45 * <p> +46 * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version +47 * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert +48 * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be +49 * identified.</p> +50 * +51 * @author Dale Visser +52 */ +53 @Experimental +54 public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { +55 +56 /** +57 * The logger. +58 */ +59 private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class); +60 +61 /** +62 * Used when compiling file scanning regex patterns. +63 */ +64 private static final int REGEX_OPTIONS = Pattern.DOTALL +65 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE; +66 +67 /** +68 * Regex to extract the product information. +69 */ +70 private static final Pattern PROJECT = Pattern.compile( +71 "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS); +72 +73 /** +74 * Regex to extract product and version information. 75 * -76 * Group 2: Version -77 */ -78 private static final Pattern SET_VERSION = Pattern -79 .compile( -80 "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)", -81 REGEX_OPTIONS); -82 -83 /** -84 * Detects files that can be analyzed. -85 */ -86 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake") -87 .addFilenames("CMakeLists.txt").build(); -88 -89 /** -90 * A reference to SHA1 message digest. -91 */ -92 private static MessageDigest sha1 = null; -93 -94 static { -95 try { -96 sha1 = MessageDigest.getInstance("SHA1"); -97 } catch (NoSuchAlgorithmException e) { -98 LOGGER.error(e.getMessage()); -99 } -100 } -101 -102 /** -103 * Returns the name of the CMake analyzer. -104 * -105 * @return the name of the analyzer +76 * Group 1: Product +77 * +78 * Group 2: Version +79 */ +80 private static final Pattern SET_VERSION = Pattern +81 .compile( +82 "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)", +83 REGEX_OPTIONS); +84 +85 /** +86 * Detects files that can be analyzed. +87 */ +88 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake") +89 .addFilenames("CMakeLists.txt").build(); +90 +91 /** +92 * A reference to SHA1 message digest. +93 */ +94 private static MessageDigest sha1 = null; +95 +96 static { +97 try { +98 sha1 = MessageDigest.getInstance("SHA1"); +99 } catch (NoSuchAlgorithmException e) { +100 LOGGER.error(e.getMessage()); +101 } +102 } +103 +104 /** +105 * Returns the name of the CMake analyzer. 106 * -107 */ -108 @Override -109 public String getName() { -110 return "CMake Analyzer"; -111 } -112 -113 /** -114 * Tell that we are used for information collection. -115 * -116 * @return INFORMATION_COLLECTION -117 */ -118 @Override -119 public AnalysisPhase getAnalysisPhase() { -120 return AnalysisPhase.INFORMATION_COLLECTION; -121 } -122 -123 /** -124 * Returns the set of supported file extensions. -125 * -126 * @return the set of supported file extensions -127 */ -128 @Override -129 protected FileFilter getFileFilter() { -130 return FILTER; -131 } -132 -133 /** -134 * No-op initializer implementation. -135 * -136 * @throws Exception never thrown -137 */ -138 @Override -139 protected void initializeFileTypeAnalyzer() throws Exception { -140 // Nothing to do here. -141 } -142 -143 /** -144 * Analyzes python packages and adds evidence to the dependency. -145 * -146 * @param dependency the dependency being analyzed -147 * @param engine the engine being used to perform the scan -148 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency -149 */ -150 @Override -151 protected void analyzeFileType(Dependency dependency, Engine engine) -152 throws AnalysisException { -153 final File file = dependency.getActualFile(); -154 final String parentName = file.getParentFile().getName(); -155 final String name = file.getName(); -156 dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name)); -157 String contents; -158 try { -159 contents = FileUtils.readFileToString(file).trim(); -160 } catch (IOException e) { -161 throw new AnalysisException( -162 "Problem occurred while reading dependency file.", e); -163 } -164 -165 if (StringUtils.isNotBlank(contents)) { -166 final Matcher m = PROJECT.matcher(contents); -167 int count = 0; -168 while (m.find()) { -169 count++; -170 LOGGER.debug(String.format( -171 "Found project command match with %d groups: %s", -172 m.groupCount(), m.group(0))); -173 final String group = m.group(1); -174 LOGGER.debug("Group 1: " + group); -175 dependency.getProductEvidence().addEvidence(name, "Project", -176 group, Confidence.HIGH); -177 } -178 LOGGER.debug("Found {} matches.", count); -179 analyzeSetVersionCommand(dependency, engine, contents); -180 } -181 } -182 -183 /** -184 * Extracts the version information from the contents. If more then one version is found additional dependencies are added to -185 * the dependency list. -186 * -187 * @param dependency the dependency being analyzed -188 * @param engine the dependency-check engine -189 * @param contents the version information -190 */ -191 private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) { -192 Dependency currentDep = dependency; -193 -194 final Matcher m = SET_VERSION.matcher(contents); -195 int count = 0; -196 while (m.find()) { -197 count++; -198 LOGGER.debug("Found project command match with {} groups: {}", -199 m.groupCount(), m.group(0)); -200 String product = m.group(1); -201 final String version = m.group(2); -202 LOGGER.debug("Group 1: " + product); -203 LOGGER.debug("Group 2: " + version); -204 final String aliasPrefix = "ALIASOF_"; -205 if (product.startsWith(aliasPrefix)) { -206 product = product.replaceFirst(aliasPrefix, ""); -207 } -208 if (count > 1) { -209 //TODO - refactor so we do not assign to the parameter (checkstyle) -210 currentDep = new Dependency(dependency.getActualFile()); -211 currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product)); -212 final String filePath = String.format("%s:%s", dependency.getFilePath(), product); -213 currentDep.setFilePath(filePath); -214 -215 byte[] path; -216 try { -217 path = filePath.getBytes("UTF-8"); -218 } catch (UnsupportedEncodingException ex) { -219 path = filePath.getBytes(); -220 } -221 currentDep.setSha1sum(Checksum.getHex(sha1.digest(path))); -222 engine.getDependencies().add(currentDep); -223 } -224 final String source = currentDep.getDisplayFileName(); -225 currentDep.getProductEvidence().addEvidence(source, "Product", -226 product, Confidence.MEDIUM); -227 currentDep.getVersionEvidence().addEvidence(source, "Version", -228 version, Confidence.MEDIUM); -229 } -230 LOGGER.debug(String.format("Found %d matches.", count)); -231 } -232 -233 @Override -234 protected String getAnalyzerEnabledSettingKey() { -235 return Settings.KEYS.ANALYZER_CMAKE_ENABLED; -236 } -237 } +107 * @return the name of the analyzer +108 * +109 */ +110 @Override +111 public String getName() { +112 return "CMake Analyzer"; +113 } +114 +115 /** +116 * Tell that we are used for information collection. +117 * +118 * @return INFORMATION_COLLECTION +119 */ +120 @Override +121 public AnalysisPhase getAnalysisPhase() { +122 return AnalysisPhase.INFORMATION_COLLECTION; +123 } +124 +125 /** +126 * Returns the set of supported file extensions. +127 * +128 * @return the set of supported file extensions +129 */ +130 @Override +131 protected FileFilter getFileFilter() { +132 return FILTER; +133 } +134 +135 /** +136 * No-op initializer implementation. +137 * +138 * @throws Exception never thrown +139 */ +140 @Override +141 protected void initializeFileTypeAnalyzer() throws Exception { +142 // Nothing to do here. +143 } +144 +145 /** +146 * Analyzes python packages and adds evidence to the dependency. +147 * +148 * @param dependency the dependency being analyzed +149 * @param engine the engine being used to perform the scan +150 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency +151 */ +152 @Override +153 protected void analyzeFileType(Dependency dependency, Engine engine) +154 throws AnalysisException { +155 final File file = dependency.getActualFile(); +156 final String parentName = file.getParentFile().getName(); +157 final String name = file.getName(); +158 dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name)); +159 String contents; +160 try { +161 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); +162 } catch (IOException e) { +163 throw new AnalysisException( +164 "Problem occurred while reading dependency file.", e); +165 } +166 +167 if (StringUtils.isNotBlank(contents)) { +168 final Matcher m = PROJECT.matcher(contents); +169 int count = 0; +170 while (m.find()) { +171 count++; +172 LOGGER.debug(String.format( +173 "Found project command match with %d groups: %s", +174 m.groupCount(), m.group(0))); +175 final String group = m.group(1); +176 LOGGER.debug("Group 1: " + group); +177 dependency.getProductEvidence().addEvidence(name, "Project", +178 group, Confidence.HIGH); +179 } +180 LOGGER.debug("Found {} matches.", count); +181 analyzeSetVersionCommand(dependency, engine, contents); +182 } +183 } +184 +185 /** +186 * Extracts the version information from the contents. If more then one version is found additional dependencies are added to +187 * the dependency list. +188 * +189 * @param dependency the dependency being analyzed +190 * @param engine the dependency-check engine +191 * @param contents the version information +192 */ +193 private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) { +194 Dependency currentDep = dependency; +195 +196 final Matcher m = SET_VERSION.matcher(contents); +197 int count = 0; +198 while (m.find()) { +199 count++; +200 LOGGER.debug("Found project command match with {} groups: {}", +201 m.groupCount(), m.group(0)); +202 String product = m.group(1); +203 final String version = m.group(2); +204 LOGGER.debug("Group 1: " + product); +205 LOGGER.debug("Group 2: " + version); +206 final String aliasPrefix = "ALIASOF_"; +207 if (product.startsWith(aliasPrefix)) { +208 product = product.replaceFirst(aliasPrefix, ""); +209 } +210 if (count > 1) { +211 //TODO - refactor so we do not assign to the parameter (checkstyle) +212 currentDep = new Dependency(dependency.getActualFile()); +213 currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product)); +214 final String filePath = String.format("%s:%s", dependency.getFilePath(), product); +215 currentDep.setFilePath(filePath); +216 +217 byte[] path; +218 try { +219 path = filePath.getBytes("UTF-8"); +220 } catch (UnsupportedEncodingException ex) { +221 path = filePath.getBytes(); +222 } +223 currentDep.setSha1sum(Checksum.getHex(sha1.digest(path))); +224 engine.getDependencies().add(currentDep); +225 } +226 final String source = currentDep.getDisplayFileName(); +227 currentDep.getProductEvidence().addEvidence(source, "Product", +228 product, Confidence.MEDIUM); +229 currentDep.getVersionEvidence().addEvidence(source, "Version", +230 version, Confidence.MEDIUM); +231 } +232 LOGGER.debug(String.format("Found %d matches.", count)); +233 } +234 +235 @Override +236 protected String getAnalyzerEnabledSettingKey() { +237 return Settings.KEYS.ANALYZER_CMAKE_ENABLED; +238 } +239 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html index 00fd6e53d..c20446fa5 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html @@ -59,726 +59,756 @@ 51 import org.slf4j.LoggerFactory; 52 53 /** -54 * CPEAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated CPE. It uses -55 * the evidence contained within the dependency to search the Lucene index. -56 * -57 * @author Jeremy Long -58 */ -59 public class CPEAnalyzer implements Analyzer { -60 -61 /** -62 * The Logger. -63 */ -64 private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class); -65 /** -66 * The maximum number of query results to return. -67 */ -68 static final int MAX_QUERY_RESULTS = 25; -69 /** -70 * The weighting boost to give terms when constructing the Lucene query. -71 */ -72 static final String WEIGHTING_BOOST = "^5"; -73 /** -74 * A string representation of a regular expression defining characters utilized within the CPE Names. -75 */ -76 static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]"; -77 /** -78 * A string representation of a regular expression used to remove all but alpha characters. -79 */ -80 static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*"; -81 /** -82 * The additional size to add to a new StringBuilder to account for extra data that will be written into the string. -83 */ -84 static final int STRING_BUILDER_BUFFER = 20; -85 /** -86 * The CPE in memory index. +54 * CPEAnalyzer is a utility class that takes a project dependency and attempts +55 * to discern if there is an associated CPE. It uses the evidence contained +56 * within the dependency to search the Lucene index. +57 * +58 * @author Jeremy Long +59 */ +60 public class CPEAnalyzer implements Analyzer { +61 +62 /** +63 * The Logger. +64 */ +65 private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class); +66 /** +67 * The maximum number of query results to return. +68 */ +69 static final int MAX_QUERY_RESULTS = 25; +70 /** +71 * The weighting boost to give terms when constructing the Lucene query. +72 */ +73 static final String WEIGHTING_BOOST = "^5"; +74 /** +75 * A string representation of a regular expression defining characters +76 * utilized within the CPE Names. +77 */ +78 static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]"; +79 /** +80 * A string representation of a regular expression used to remove all but +81 * alpha characters. +82 */ +83 static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*"; +84 /** +85 * The additional size to add to a new StringBuilder to account for extra +86 * data that will be written into the string. 87 */ -88 private CpeMemoryIndex cpe; +88 static final int STRING_BUILDER_BUFFER = 20; 89 /** -90 * The CVE Database. +90 * The CPE in memory index. 91 */ -92 private CveDB cve; -93 -94 /** -95 * The URL to perform a search of the NVD CVE data at NIST. -96 */ -97 public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s"; -98 -99 /** -100 * Returns the name of this analyzer. -101 * -102 * @return the name of this analyzer. -103 */ -104 @Override -105 public String getName() { -106 return "CPE Analyzer"; -107 } -108 -109 /** -110 * Returns the analysis phase that this analyzer should run in. -111 * -112 * @return the analysis phase that this analyzer should run in. -113 */ -114 @Override -115 public AnalysisPhase getAnalysisPhase() { -116 return AnalysisPhase.IDENTIFIER_ANALYSIS; -117 } -118 -119 /** -120 * Creates the CPE Lucene Index. -121 * -122 * @throws Exception is thrown if there is an issue opening the index. -123 */ -124 @Override -125 public void initialize() throws Exception { -126 this.open(); -127 } -128 -129 /** -130 * Opens the data source. -131 * -132 * @throws IOException when the Lucene directory to be queried does not exist or is corrupt. -133 * @throws DatabaseException when the database throws an exception. This usually occurs when the database is in use by another -134 * process. -135 */ -136 public void open() throws IOException, DatabaseException { -137 if (!isOpen()) { -138 cve = new CveDB(); -139 cve.open(); -140 cpe = CpeMemoryIndex.getInstance(); -141 try { -142 LOGGER.info("Creating the CPE Index"); -143 final long creationStart = System.currentTimeMillis(); -144 cpe.open(cve); -145 LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart); -146 } catch (IndexException ex) { -147 LOGGER.debug("IndexException", ex); -148 throw new DatabaseException(ex); -149 } -150 } -151 } -152 -153 /** -154 * Closes the data sources. -155 */ -156 @Override -157 public void close() { -158 if (cpe != null) { -159 cpe.close(); -160 cpe = null; -161 } -162 if (cve != null) { -163 cve.close(); -164 cve = null; -165 } -166 } -167 -168 public boolean isOpen() { -169 return cpe != null && cpe.isOpen(); -170 } -171 -172 /** -173 * Searches the data store of CPE entries, trying to identify the CPE for the given dependency based on the evidence contained -174 * within. The dependency passed in is updated with any identified CPE values. -175 * -176 * @param dependency the dependency to search for CPE entries on. -177 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. -178 * @throws IOException is thrown when an IOException occurs. -179 * @throws ParseException is thrown when the Lucene query cannot be parsed. -180 */ -181 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { -182 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit -183 String vendors = ""; -184 String products = ""; -185 for (Confidence confidence : Confidence.values()) { -186 if (dependency.getVendorEvidence().contains(confidence)) { -187 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); -188 LOGGER.debug("vendor search: {}", vendors); -189 } -190 if (dependency.getProductEvidence().contains(confidence)) { -191 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); -192 LOGGER.debug("product search: {}", products); -193 } -194 if (!vendors.isEmpty() && !products.isEmpty()) { -195 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(), -196 dependency.getVendorEvidence().getWeighting()); -197 if (entries == null) { -198 continue; -199 } -200 boolean identifierAdded = false; -201 for (IndexEntry e : entries) { -202 LOGGER.debug("Verifying entry: {}", e); -203 if (verifyEntry(e, dependency)) { -204 final String vendor = e.getVendor(); -205 final String product = e.getProduct(); -206 LOGGER.debug("identified vendor/product: {}/{}", vendor, product); -207 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); -208 } -209 } -210 if (identifierAdded) { -211 break; -212 } -213 } -214 } -215 } -216 -217 /** -218 * Returns the text created by concatenating the text and the values from the EvidenceCollection (filtered for a specific -219 * confidence). This attempts to prevent duplicate terms from being added.<br/<br/> Note, if the evidence is longer then 200 -220 * characters it will be truncated. -221 * -222 * @param text the base text. -223 * @param ec an EvidenceCollection -224 * @param confidenceFilter a Confidence level to filter the evidence by. -225 * @return the new evidence text -226 */ -227 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { -228 final String txt = (text == null) ? "" : text; -229 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); -230 sb.append(' ').append(txt).append(' '); -231 for (Evidence e : ec.iterator(confidenceFilter)) { -232 String value = e.getValue(); -233 -234 //hack to get around the fact that lucene does a really good job of recognizing domains and not -235 // splitting them. TODO - put together a better lucene analyzer specific to the domain. -236 if (value.startsWith("http://")) { -237 value = value.substring(7).replaceAll("\\.", " "); -238 } -239 if (value.startsWith("https://")) { -240 value = value.substring(8).replaceAll("\\.", " "); -241 } -242 if (sb.indexOf(" " + value + " ") < 0) { -243 sb.append(value).append(' '); -244 } -245 } -246 return sb.toString().trim(); -247 } -248 -249 /** -250 * <p> -251 * Searches the Lucene CPE index to identify possible CPE entries associated with the supplied vendor, product, and -252 * version.</p> -253 * -254 * <p> -255 * If either the vendorWeightings or productWeightings lists have been populated this data is used to add weighting factors to -256 * the search.</p> -257 * -258 * @param vendor the text used to search the vendor field -259 * @param product the text used to search the product field -260 * @param vendorWeightings a list of strings to use to add weighting factors to the vendor field -261 * @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search -262 * @return a list of possible CPE values -263 */ -264 protected List<IndexEntry> searchCPE(String vendor, String product, -265 Set<String> vendorWeightings, Set<String> productWeightings) { -266 -267 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); -268 -269 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); -270 if (searchString == null) { -271 return ret; -272 } -273 try { -274 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); -275 for (ScoreDoc d : docs.scoreDocs) { -276 if (d.score >= 0.08) { -277 final Document doc = cpe.getDocument(d.doc); -278 final IndexEntry entry = new IndexEntry(); -279 entry.setVendor(doc.get(Fields.VENDOR)); -280 entry.setProduct(doc.get(Fields.PRODUCT)); -281 entry.setSearchScore(d.score); -282 if (!ret.contains(entry)) { -283 ret.add(entry); -284 } -285 } -286 } -287 return ret; -288 } catch (ParseException ex) { -289 LOGGER.warn("An error occurred querying the CPE data. See the log for more details."); -290 LOGGER.info("Unable to parse: {}", searchString, ex); -291 } catch (IOException ex) { -292 LOGGER.warn("An error occurred reading CPE data. See the log for more details."); -293 LOGGER.info("IO Error with search string: {}", searchString, ex); -294 } -295 return null; -296 } -297 -298 /** -299 * <p> -300 * Builds a Lucene search string by properly escaping data and constructing a valid search query.</p> -301 * -302 * <p> -303 * If either the possibleVendor or possibleProducts lists have been populated this data is used to add weighting factors to -304 * the search string generated.</p> -305 * -306 * @param vendor text to search the vendor field -307 * @param product text to search the product field -308 * @param vendorWeighting a list of strings to apply to the vendor to boost the terms weight -309 * @param productWeightings a list of strings to apply to the product to boost the terms weight -310 * @return the Lucene query -311 */ -312 protected String buildSearch(String vendor, String product, -313 Set<String> vendorWeighting, Set<String> productWeightings) { -314 final String v = vendor; //.replaceAll("[^\\w\\d]", " "); -315 final String p = product; //.replaceAll("[^\\w\\d]", " "); -316 final StringBuilder sb = new StringBuilder(v.length() + p.length() -317 + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER); -318 -319 if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) { -320 return null; -321 } -322 sb.append(" AND "); -323 if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) { -324 return null; -325 } -326 return sb.toString(); -327 } -328 -329 /** -330 * This method constructs a Lucene query for a given field. The searchText is split into separate words and if the word is -331 * within the list of weighted words then an additional weighting is applied to the term as it is appended into the query. -332 * -333 * @param sb a StringBuilder that the query text will be appended to. -334 * @param field the field within the Lucene index that the query is searching. -335 * @param searchText text used to construct the query. -336 * @param weightedText a list of terms that will be considered higher importance when searching. -337 * @return if the append was successful. -338 */ -339 private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) { -340 sb.append(' ').append(field).append(":( "); +92 private CpeMemoryIndex cpe; +93 /** +94 * The CVE Database. +95 */ +96 private CveDB cve; +97 +98 /** +99 * The URL to perform a search of the NVD CVE data at NIST. +100 */ +101 public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s"; +102 +103 /** +104 * Returns the name of this analyzer. +105 * +106 * @return the name of this analyzer. +107 */ +108 @Override +109 public String getName() { +110 return "CPE Analyzer"; +111 } +112 +113 /** +114 * Returns the analysis phase that this analyzer should run in. +115 * +116 * @return the analysis phase that this analyzer should run in. +117 */ +118 @Override +119 public AnalysisPhase getAnalysisPhase() { +120 return AnalysisPhase.IDENTIFIER_ANALYSIS; +121 } +122 +123 /** +124 * Creates the CPE Lucene Index. +125 * +126 * @throws Exception is thrown if there is an issue opening the index. +127 */ +128 @Override +129 public void initialize() throws Exception { +130 this.open(); +131 } +132 +133 /** +134 * Opens the data source. +135 * +136 * @throws IOException when the Lucene directory to be queried does not +137 * exist or is corrupt. +138 * @throws DatabaseException when the database throws an exception. This +139 * usually occurs when the database is in use by another process. +140 */ +141 public void open() throws IOException, DatabaseException { +142 if (!isOpen()) { +143 cve = new CveDB(); +144 cve.open(); +145 cpe = CpeMemoryIndex.getInstance(); +146 try { +147 LOGGER.info("Creating the CPE Index"); +148 final long creationStart = System.currentTimeMillis(); +149 cpe.open(cve); +150 LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart); +151 } catch (IndexException ex) { +152 LOGGER.debug("IndexException", ex); +153 throw new DatabaseException(ex); +154 } +155 } +156 } +157 +158 /** +159 * Closes the data sources. +160 */ +161 @Override +162 public void close() { +163 if (cpe != null) { +164 cpe.close(); +165 cpe = null; +166 } +167 if (cve != null) { +168 cve.close(); +169 cve = null; +170 } +171 } +172 +173 public boolean isOpen() { +174 return cpe != null && cpe.isOpen(); +175 } +176 +177 /** +178 * Searches the data store of CPE entries, trying to identify the CPE for +179 * the given dependency based on the evidence contained within. The +180 * dependency passed in is updated with any identified CPE values. +181 * +182 * @param dependency the dependency to search for CPE entries on. +183 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. +184 * @throws IOException is thrown when an IOException occurs. +185 * @throws ParseException is thrown when the Lucene query cannot be parsed. +186 */ +187 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { +188 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit +189 String vendors = ""; +190 String products = ""; +191 for (Confidence confidence : Confidence.values()) { +192 if (dependency.getVendorEvidence().contains(confidence)) { +193 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); +194 LOGGER.debug("vendor search: {}", vendors); +195 } +196 if (dependency.getProductEvidence().contains(confidence)) { +197 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); +198 LOGGER.debug("product search: {}", products); +199 } +200 if (!vendors.isEmpty() && !products.isEmpty()) { +201 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(), +202 dependency.getProductEvidence().getWeighting()); +203 if (entries == null) { +204 continue; +205 } +206 boolean identifierAdded = false; +207 for (IndexEntry e : entries) { +208 LOGGER.debug("Verifying entry: {}", e); +209 if (verifyEntry(e, dependency)) { +210 final String vendor = e.getVendor(); +211 final String product = e.getProduct(); +212 LOGGER.debug("identified vendor/product: {}/{}", vendor, product); +213 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); +214 } +215 } +216 if (identifierAdded) { +217 break; +218 } +219 } +220 } +221 } +222 +223 /** +224 * Returns the text created by concatenating the text and the values from +225 * the EvidenceCollection (filtered for a specific confidence). This +226 * attempts to prevent duplicate terms from being added.<br/<br/> Note, if +227 * the evidence is longer then 200 characters it will be truncated. +228 * +229 * @param text the base text. +230 * @param ec an EvidenceCollection +231 * @param confidenceFilter a Confidence level to filter the evidence by. +232 * @return the new evidence text +233 */ +234 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { +235 final String txt = (text == null) ? "" : text; +236 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); +237 sb.append(' ').append(txt).append(' '); +238 for (Evidence e : ec.iterator(confidenceFilter)) { +239 String value = e.getValue(); +240 +241 //hack to get around the fact that lucene does a really good job of recognizing domains and not +242 // splitting them. TODO - put together a better lucene analyzer specific to the domain. +243 if (value.startsWith("http://")) { +244 value = value.substring(7).replaceAll("\\.", " "); +245 } +246 if (value.startsWith("https://")) { +247 value = value.substring(8).replaceAll("\\.", " "); +248 } +249 if (sb.indexOf(" " + value + " ") < 0) { +250 sb.append(value).append(' '); +251 } +252 } +253 return sb.toString().trim(); +254 } +255 +256 /** +257 * <p> +258 * Searches the Lucene CPE index to identify possible CPE entries associated +259 * with the supplied vendor, product, and version.</p> +260 * +261 * <p> +262 * If either the vendorWeightings or productWeightings lists have been +263 * populated this data is used to add weighting factors to the search.</p> +264 * +265 * @param vendor the text used to search the vendor field +266 * @param product the text used to search the product field +267 * @param vendorWeightings a list of strings to use to add weighting factors +268 * to the vendor field +269 * @param productWeightings Adds a list of strings that will be used to add +270 * weighting factors to the product search +271 * @return a list of possible CPE values +272 */ +273 protected List<IndexEntry> searchCPE(String vendor, String product, +274 Set<String> vendorWeightings, Set<String> productWeightings) { +275 +276 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); +277 +278 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); +279 if (searchString == null) { +280 return ret; +281 } +282 try { +283 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); +284 for (ScoreDoc d : docs.scoreDocs) { +285 if (d.score >= 0.08) { +286 final Document doc = cpe.getDocument(d.doc); +287 final IndexEntry entry = new IndexEntry(); +288 entry.setVendor(doc.get(Fields.VENDOR)); +289 entry.setProduct(doc.get(Fields.PRODUCT)); +290 entry.setSearchScore(d.score); +291 if (!ret.contains(entry)) { +292 ret.add(entry); +293 } +294 } +295 } +296 return ret; +297 } catch (ParseException ex) { +298 LOGGER.warn("An error occurred querying the CPE data. See the log for more details."); +299 LOGGER.info("Unable to parse: {}", searchString, ex); +300 } catch (IOException ex) { +301 LOGGER.warn("An error occurred reading CPE data. See the log for more details."); +302 LOGGER.info("IO Error with search string: {}", searchString, ex); +303 } +304 return null; +305 } +306 +307 /** +308 * <p> +309 * Builds a Lucene search string by properly escaping data and constructing +310 * a valid search query.</p> +311 * +312 * <p> +313 * If either the possibleVendor or possibleProducts lists have been +314 * populated this data is used to add weighting factors to the search string +315 * generated.</p> +316 * +317 * @param vendor text to search the vendor field +318 * @param product text to search the product field +319 * @param vendorWeighting a list of strings to apply to the vendor to boost +320 * the terms weight +321 * @param productWeightings a list of strings to apply to the product to +322 * boost the terms weight +323 * @return the Lucene query +324 */ +325 protected String buildSearch(String vendor, String product, +326 Set<String> vendorWeighting, Set<String> productWeightings) { +327 final String v = vendor; //.replaceAll("[^\\w\\d]", " "); +328 final String p = product; //.replaceAll("[^\\w\\d]", " "); +329 final StringBuilder sb = new StringBuilder(v.length() + p.length() +330 + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER); +331 +332 if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) { +333 return null; +334 } +335 sb.append(" AND "); +336 if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) { +337 return null; +338 } +339 return sb.toString(); +340 } 341 -342 final String cleanText = cleanseText(searchText); -343 -344 if (cleanText.isEmpty()) { -345 return false; -346 } -347 -348 if (weightedText == null || weightedText.isEmpty()) { -349 LuceneUtils.appendEscapedLuceneQuery(sb, cleanText); -350 } else { -351 final StringTokenizer tokens = new StringTokenizer(cleanText); -352 while (tokens.hasMoreElements()) { -353 final String word = tokens.nextToken(); -354 StringBuilder temp = null; -355 for (String weighted : weightedText) { -356 final String weightedStr = cleanseText(weighted); -357 if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) { -358 temp = new StringBuilder(word.length() + 2); -359 LuceneUtils.appendEscapedLuceneQuery(temp, word); -360 temp.append(WEIGHTING_BOOST); -361 if (!word.equalsIgnoreCase(weightedStr)) { -362 temp.append(' '); -363 LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr); -364 temp.append(WEIGHTING_BOOST); -365 } -366 break; -367 } -368 } -369 sb.append(' '); -370 if (temp == null) { -371 LuceneUtils.appendEscapedLuceneQuery(sb, word); -372 } else { -373 sb.append(temp); -374 } -375 } -376 } -377 sb.append(" ) "); -378 return true; -379 } -380 -381 /** -382 * Removes characters from the input text that are not used within the CPE index. -383 * -384 * @param text is the text to remove the characters from. -385 * @return the text having removed some characters. -386 */ -387 private String cleanseText(String text) { -388 return text.replaceAll(CLEANSE_CHARACTER_RX, " "); -389 } -390 -391 /** -392 * Compares two strings after lower casing them and removing the non-alpha characters. -393 * -394 * @param l string one to compare. -395 * @param r string two to compare. -396 * @return whether or not the two strings are similar. -397 */ -398 private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) { -399 if (l == null || r == null) { -400 return false; -401 } -402 -403 final String left = l.replaceAll(CLEANSE_NONALPHA_RX, ""); -404 final String right = r.replaceAll(CLEANSE_NONALPHA_RX, ""); -405 return left.equalsIgnoreCase(right); -406 } -407 -408 /** -409 * Ensures that the CPE Identified matches the dependency. This validates that the product, vendor, and version information -410 * for the CPE are contained within the dependencies evidence. -411 * -412 * @param entry a CPE entry. -413 * @param dependency the dependency that the CPE entries could be for. -414 * @return whether or not the entry is valid. -415 */ -416 private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) { -417 boolean isValid = false; -418 -419 //TODO - does this nullify some of the fuzzy matching that happens in the lucene search? -420 // for instance CPE some-component and in the evidence we have SomeComponent. -421 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) -422 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { -423 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) -424 isValid = true; -425 } -426 return isValid; -427 } -428 -429 /** -430 * Used to determine if the EvidenceCollection contains a specific string. +342 /** +343 * This method constructs a Lucene query for a given field. The searchText +344 * is split into separate words and if the word is within the list of +345 * weighted words then an additional weighting is applied to the term as it +346 * is appended into the query. +347 * +348 * @param sb a StringBuilder that the query text will be appended to. +349 * @param field the field within the Lucene index that the query is +350 * searching. +351 * @param searchText text used to construct the query. +352 * @param weightedText a list of terms that will be considered higher +353 * importance when searching. +354 * @return if the append was successful. +355 */ +356 private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) { +357 sb.append(' ').append(field).append(":( "); +358 +359 final String cleanText = cleanseText(searchText); +360 +361 if (cleanText.isEmpty()) { +362 return false; +363 } +364 +365 if (weightedText == null || weightedText.isEmpty()) { +366 LuceneUtils.appendEscapedLuceneQuery(sb, cleanText); +367 } else { +368 final StringTokenizer tokens = new StringTokenizer(cleanText); +369 while (tokens.hasMoreElements()) { +370 final String word = tokens.nextToken(); +371 StringBuilder temp = null; +372 for (String weighted : weightedText) { +373 final String weightedStr = cleanseText(weighted); +374 if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) { +375 temp = new StringBuilder(word.length() + 2); +376 LuceneUtils.appendEscapedLuceneQuery(temp, word); +377 temp.append(WEIGHTING_BOOST); +378 if (!word.equalsIgnoreCase(weightedStr)) { +379 temp.append(' '); +380 LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr); +381 temp.append(WEIGHTING_BOOST); +382 } +383 break; +384 } +385 } +386 sb.append(' '); +387 if (temp == null) { +388 LuceneUtils.appendEscapedLuceneQuery(sb, word); +389 } else { +390 sb.append(temp); +391 } +392 } +393 } +394 sb.append(" ) "); +395 return true; +396 } +397 +398 /** +399 * Removes characters from the input text that are not used within the CPE +400 * index. +401 * +402 * @param text is the text to remove the characters from. +403 * @return the text having removed some characters. +404 */ +405 private String cleanseText(String text) { +406 return text.replaceAll(CLEANSE_CHARACTER_RX, " "); +407 } +408 +409 /** +410 * Compares two strings after lower casing them and removing the non-alpha +411 * characters. +412 * +413 * @param l string one to compare. +414 * @param r string two to compare. +415 * @return whether or not the two strings are similar. +416 */ +417 private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) { +418 if (l == null || r == null) { +419 return false; +420 } +421 +422 final String left = l.replaceAll(CLEANSE_NONALPHA_RX, ""); +423 final String right = r.replaceAll(CLEANSE_NONALPHA_RX, ""); +424 return left.equalsIgnoreCase(right); +425 } +426 +427 /** +428 * Ensures that the CPE Identified matches the dependency. This validates +429 * that the product, vendor, and version information for the CPE are +430 * contained within the dependencies evidence. 431 * -432 * @param ec an EvidenceCollection -433 * @param text the text to search for -434 * @return whether or not the EvidenceCollection contains the string +432 * @param entry a CPE entry. +433 * @param dependency the dependency that the CPE entries could be for. +434 * @return whether or not the entry is valid. 435 */ -436 private boolean collectionContainsString(EvidenceCollection ec, String text) { -437 //TODO - likely need to change the split... not sure if this will work for CPE with special chars -438 if (text == null) { -439 return false; -440 } -441 final String[] words = text.split("[\\s_-]"); -442 final List<String> list = new ArrayList<String>(); -443 String tempWord = null; -444 for (String word : words) { -445 /* -446 single letter words should be concatenated with the next word. -447 so { "m", "core", "sample" } -> { "mcore", "sample" } -448 */ -449 if (tempWord != null) { -450 list.add(tempWord + word); -451 tempWord = null; -452 } else if (word.length() <= 2) { -453 tempWord = word; -454 } else { -455 list.add(word); -456 } -457 } -458 if (tempWord != null) { -459 if (!list.isEmpty()) { -460 final String tmp = list.get(list.size() - 1) + tempWord; -461 list.add(tmp); -462 } else { -463 list.add(tempWord); -464 } -465 } -466 if (list.isEmpty()) { -467 return false; -468 } -469 boolean contains = true; -470 for (String word : list) { -471 contains &= ec.containsUsedString(word); -472 } -473 return contains; -474 } -475 -476 /** -477 * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency. -478 * -479 * @param dependency The Dependency to analyze. -480 * @param engine The analysis engine -481 * @throws AnalysisException is thrown if there is an issue analyzing the dependency. -482 */ -483 @Override -484 public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException { -485 try { -486 determineCPE(dependency); -487 } catch (CorruptIndexException ex) { -488 throw new AnalysisException("CPE Index is corrupt.", ex); -489 } catch (IOException ex) { -490 throw new AnalysisException("Failure opening the CPE Index.", ex); -491 } catch (ParseException ex) { -492 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); -493 } +436 private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) { +437 boolean isValid = false; +438 +439 //TODO - does this nullify some of the fuzzy matching that happens in the lucene search? +440 // for instance CPE some-component and in the evidence we have SomeComponent. +441 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) +442 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { +443 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) +444 isValid = true; +445 } +446 return isValid; +447 } +448 +449 /** +450 * Used to determine if the EvidenceCollection contains a specific string. +451 * +452 * @param ec an EvidenceCollection +453 * @param text the text to search for +454 * @return whether or not the EvidenceCollection contains the string +455 */ +456 private boolean collectionContainsString(EvidenceCollection ec, String text) { +457 //TODO - likely need to change the split... not sure if this will work for CPE with special chars +458 if (text == null) { +459 return false; +460 } +461 final String[] words = text.split("[\\s_-]"); +462 final List<String> list = new ArrayList<String>(); +463 String tempWord = null; +464 for (String word : words) { +465 /* +466 single letter words should be concatenated with the next word. +467 so { "m", "core", "sample" } -> { "mcore", "sample" } +468 */ +469 if (tempWord != null) { +470 list.add(tempWord + word); +471 tempWord = null; +472 } else if (word.length() <= 2) { +473 tempWord = word; +474 } else { +475 list.add(word); +476 } +477 } +478 if (tempWord != null) { +479 if (!list.isEmpty()) { +480 final String tmp = list.get(list.size() - 1) + tempWord; +481 list.add(tmp); +482 } else { +483 list.add(tempWord); +484 } +485 } +486 if (list.isEmpty()) { +487 return false; +488 } +489 boolean contains = true; +490 for (String word : list) { +491 contains &= ec.containsUsedString(word); +492 } +493 return contains; 494 } 495 496 /** -497 * Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then validated to find -498 * only CPEs that are valid for the given dependency. It is possible that the CPE identified is a best effort "guess" based on -499 * the vendor, product, and version information. -500 * -501 * @param dependency the Dependency being analyzed -502 * @param vendor the vendor for the CPE being analyzed -503 * @param product the product for the CPE being analyzed -504 * @param currentConfidence the current confidence being used during analysis -505 * @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code> -506 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported -507 */ -508 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, -509 Confidence currentConfidence) throws UnsupportedEncodingException { -510 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); -511 DependencyVersion bestGuess = new DependencyVersion("-"); -512 Confidence bestGuessConf = null; -513 boolean hasBroadMatch = false; -514 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); -515 for (Confidence conf : Confidence.values()) { -516 // if (conf.compareTo(currentConfidence) > 0) { -517 // break; -518 // } -519 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { -520 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); -521 if (evVer == null) { -522 continue; -523 } -524 for (VulnerableSoftware vs : cpes) { -525 DependencyVersion dbVer; -526 if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) { -527 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate()); -528 } else { -529 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); -530 } -531 if (dbVer == null) { //special case, no version specified - everything is vulnerable -532 hasBroadMatch = true; -533 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -534 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); -535 collected.add(match); -536 } else if (evVer.equals(dbVer)) { //yeah! exact match -537 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -538 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); -539 collected.add(match); -540 } else { -541 //TODO the following isn't quite right is it? need to think about this guessing game a bit more. -542 if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() -543 && evVer.matchesAtLeastThreeLevels(dbVer)) { -544 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -545 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { -546 bestGuess = dbVer; -547 bestGuessConf = conf; -548 } -549 } -550 } -551 } -552 } -553 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -554 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { -555 bestGuess = evVer; -556 bestGuessConf = conf; +497 * Analyzes a dependency and attempts to determine if there are any CPE +498 * identifiers for this dependency. +499 * +500 * @param dependency The Dependency to analyze. +501 * @param engine The analysis engine +502 * @throws AnalysisException is thrown if there is an issue analyzing the +503 * dependency. +504 */ +505 @Override +506 public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException { +507 try { +508 determineCPE(dependency); +509 } catch (CorruptIndexException ex) { +510 throw new AnalysisException("CPE Index is corrupt.", ex); +511 } catch (IOException ex) { +512 throw new AnalysisException("Failure opening the CPE Index.", ex); +513 } catch (ParseException ex) { +514 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); +515 } +516 } +517 +518 /** +519 * Retrieves a list of CPE values from the CveDB based on the vendor and +520 * product passed in. The list is then validated to find only CPEs that are +521 * valid for the given dependency. It is possible that the CPE identified is +522 * a best effort "guess" based on the vendor, product, and version +523 * information. +524 * +525 * @param dependency the Dependency being analyzed +526 * @param vendor the vendor for the CPE being analyzed +527 * @param product the product for the CPE being analyzed +528 * @param currentConfidence the current confidence being used during +529 * analysis +530 * @return <code>true</code> if an identifier was added to the dependency; +531 * otherwise <code>false</code> +532 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported +533 */ +534 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, +535 Confidence currentConfidence) throws UnsupportedEncodingException { +536 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); +537 DependencyVersion bestGuess = new DependencyVersion("-"); +538 Confidence bestGuessConf = null; +539 boolean hasBroadMatch = false; +540 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); +541 +542 //TODO the following algorithm incorrectly identifies things as a lower version +543 // if there lower confidence evidence when the current (highest) version number +544 // is newer then anything in the NVD. +545 for (Confidence conf : Confidence.values()) { +546 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { +547 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); +548 if (evVer == null) { +549 continue; +550 } +551 for (VulnerableSoftware vs : cpes) { +552 DependencyVersion dbVer; +553 if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) { +554 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate()); +555 } else { +556 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); 557 } -558 } -559 } -560 } -561 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); -562 String url = null; -563 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. -564 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); -565 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); -566 } -567 if (bestGuessConf == null) { -568 bestGuessConf = Confidence.LOW; -569 } -570 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); -571 collected.add(match); -572 -573 Collections.sort(collected); -574 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); -575 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); -576 boolean identifierAdded = false; -577 for (IdentifierMatch m : collected) { -578 if (bestIdentifierQuality.equals(m.getConfidence()) -579 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { -580 final Identifier i = m.getIdentifier(); -581 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { -582 i.setConfidence(Confidence.LOW); -583 } else { -584 i.setConfidence(bestEvidenceQuality); -585 } -586 dependency.addIdentifier(i); -587 identifierAdded = true; -588 } -589 } -590 return identifierAdded; -591 } -592 -593 /** -594 * The confidence whether the identifier is an exact match, or a best guess. -595 */ -596 private enum IdentifierConfidence { +558 if (dbVer == null) { //special case, no version specified - everything is vulnerable +559 hasBroadMatch = true; +560 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +561 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); +562 collected.add(match); +563 } else if (evVer.equals(dbVer)) { //yeah! exact match +564 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +565 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); +566 collected.add(match); +567 } else //TODO the following isn't quite right is it? need to think about this guessing game a bit more. +568 if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() +569 && evVer.matchesAtLeastThreeLevels(dbVer)) { +570 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +571 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { +572 bestGuess = dbVer; +573 bestGuessConf = conf; +574 } +575 } +576 } +577 } +578 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +579 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { +580 bestGuess = evVer; +581 bestGuessConf = conf; +582 } +583 } +584 } +585 } +586 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); +587 String url = null; +588 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. +589 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); +590 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); +591 } +592 if (bestGuessConf == null) { +593 bestGuessConf = Confidence.LOW; +594 } +595 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); +596 collected.add(match); 597 -598 /** -599 * An exact match for the CPE. -600 */ -601 EXACT_MATCH, -602 /** -603 * A best guess for the CPE. -604 */ -605 BEST_GUESS, -606 /** -607 * The entire vendor/product group must be added (without a guess at version) because there is a CVE with a VS that only -608 * specifies vendor/product. -609 */ -610 BROAD_MATCH -611 } -612 -613 /** -614 * A simple object to hold an identifier and carry information about the confidence in the identifier. -615 */ -616 private static class IdentifierMatch implements Comparable<IdentifierMatch> { +598 Collections.sort(collected); +599 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); +600 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); +601 boolean identifierAdded = false; +602 for (IdentifierMatch m : collected) { +603 if (bestIdentifierQuality.equals(m.getConfidence()) +604 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { +605 final Identifier i = m.getIdentifier(); +606 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { +607 i.setConfidence(Confidence.LOW); +608 } else { +609 i.setConfidence(bestEvidenceQuality); +610 } +611 dependency.addIdentifier(i); +612 identifierAdded = true; +613 } +614 } +615 return identifierAdded; +616 } 617 -618 /** -619 * Constructs an IdentifierMatch. -620 * -621 * @param type the type of identifier (such as CPE) -622 * @param value the value of the identifier -623 * @param url the URL of the identifier -624 * @param identifierConfidence the confidence in the identifier: best guess or exact match -625 * @param evidenceConfidence the confidence of the evidence used to find the identifier -626 */ -627 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { -628 this.identifier = new Identifier(type, value, url); -629 this.confidence = identifierConfidence; -630 this.evidenceConfidence = evidenceConfidence; -631 } -632 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> -633 /** -634 * The confidence in the evidence used to identify this match. +618 /** +619 * The confidence whether the identifier is an exact match, or a best guess. +620 */ +621 private enum IdentifierConfidence { +622 +623 /** +624 * An exact match for the CPE. +625 */ +626 EXACT_MATCH, +627 /** +628 * A best guess for the CPE. +629 */ +630 BEST_GUESS, +631 /** +632 * The entire vendor/product group must be added (without a guess at +633 * version) because there is a CVE with a VS that only specifies +634 * vendor/product. 635 */ -636 private Confidence evidenceConfidence; -637 -638 /** -639 * Get the value of evidenceConfidence -640 * -641 * @return the value of evidenceConfidence -642 */ -643 public Confidence getEvidenceConfidence() { -644 return evidenceConfidence; -645 } -646 -647 /** -648 * Set the value of evidenceConfidence -649 * -650 * @param evidenceConfidence new value of evidenceConfidence -651 */ -652 public void setEvidenceConfidence(Confidence evidenceConfidence) { -653 this.evidenceConfidence = evidenceConfidence; -654 } -655 /** -656 * The confidence whether this is an exact match, or a best guess. -657 */ -658 private IdentifierConfidence confidence; -659 -660 /** -661 * Get the value of confidence. -662 * -663 * @return the value of confidence +636 BROAD_MATCH +637 } +638 +639 /** +640 * A simple object to hold an identifier and carry information about the +641 * confidence in the identifier. +642 */ +643 private static class IdentifierMatch implements Comparable<IdentifierMatch> { +644 +645 /** +646 * Constructs an IdentifierMatch. +647 * +648 * @param type the type of identifier (such as CPE) +649 * @param value the value of the identifier +650 * @param url the URL of the identifier +651 * @param identifierConfidence the confidence in the identifier: best +652 * guess or exact match +653 * @param evidenceConfidence the confidence of the evidence used to find +654 * the identifier +655 */ +656 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { +657 this.identifier = new Identifier(type, value, url); +658 this.confidence = identifierConfidence; +659 this.evidenceConfidence = evidenceConfidence; +660 } +661 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> +662 /** +663 * The confidence in the evidence used to identify this match. 664 */ -665 public IdentifierConfidence getConfidence() { -666 return confidence; -667 } -668 -669 /** -670 * Set the value of confidence. -671 * -672 * @param confidence new value of confidence -673 */ -674 public void setConfidence(IdentifierConfidence confidence) { -675 this.confidence = confidence; -676 } -677 /** -678 * The CPE identifier. -679 */ -680 private Identifier identifier; -681 -682 /** -683 * Get the value of identifier. -684 * -685 * @return the value of identifier +665 private Confidence evidenceConfidence; +666 +667 /** +668 * Get the value of evidenceConfidence +669 * +670 * @return the value of evidenceConfidence +671 */ +672 public Confidence getEvidenceConfidence() { +673 return evidenceConfidence; +674 } +675 +676 /** +677 * Set the value of evidenceConfidence +678 * +679 * @param evidenceConfidence new value of evidenceConfidence +680 */ +681 public void setEvidenceConfidence(Confidence evidenceConfidence) { +682 this.evidenceConfidence = evidenceConfidence; +683 } +684 /** +685 * The confidence whether this is an exact match, or a best guess. 686 */ -687 public Identifier getIdentifier() { -688 return identifier; -689 } -690 -691 /** -692 * Set the value of identifier. -693 * -694 * @param identifier new value of identifier -695 */ -696 public void setIdentifier(Identifier identifier) { -697 this.identifier = identifier; -698 } -699 //</editor-fold> -700 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> -701 -702 /** -703 * Standard toString() implementation. -704 * -705 * @return the string representation of the object -706 */ -707 @Override -708 public String toString() { -709 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence -710 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; -711 } -712 -713 /** -714 * Standard hashCode() implementation. -715 * -716 * @return the hashCode -717 */ -718 @Override -719 public int hashCode() { -720 int hash = 5; -721 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); -722 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); -723 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); -724 return hash; -725 } -726 -727 /** -728 * Standard equals implementation. -729 * -730 * @param obj the object to compare -731 * @return true if the objects are equal, otherwise false -732 */ -733 @Override -734 public boolean equals(Object obj) { -735 if (obj == null) { -736 return false; -737 } -738 if (getClass() != obj.getClass()) { -739 return false; -740 } -741 final IdentifierMatch other = (IdentifierMatch) obj; -742 if (this.evidenceConfidence != other.evidenceConfidence) { -743 return false; -744 } -745 if (this.confidence != other.confidence) { -746 return false; -747 } -748 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { -749 return false; -750 } -751 return true; -752 } -753 //</editor-fold> -754 -755 /** -756 * Standard implementation of compareTo that compares identifier confidence, evidence confidence, and then the identifier. -757 * -758 * @param o the IdentifierMatch to compare to -759 * @return the natural ordering of IdentifierMatch -760 */ -761 @Override -762 public int compareTo(IdentifierMatch o) { -763 int conf = this.confidence.compareTo(o.confidence); -764 if (conf == 0) { -765 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); -766 if (conf == 0) { -767 conf = identifier.compareTo(o.identifier); -768 } +687 private IdentifierConfidence confidence; +688 +689 /** +690 * Get the value of confidence. +691 * +692 * @return the value of confidence +693 */ +694 public IdentifierConfidence getConfidence() { +695 return confidence; +696 } +697 +698 /** +699 * Set the value of confidence. +700 * +701 * @param confidence new value of confidence +702 */ +703 public void setConfidence(IdentifierConfidence confidence) { +704 this.confidence = confidence; +705 } +706 /** +707 * The CPE identifier. +708 */ +709 private Identifier identifier; +710 +711 /** +712 * Get the value of identifier. +713 * +714 * @return the value of identifier +715 */ +716 public Identifier getIdentifier() { +717 return identifier; +718 } +719 +720 /** +721 * Set the value of identifier. +722 * +723 * @param identifier new value of identifier +724 */ +725 public void setIdentifier(Identifier identifier) { +726 this.identifier = identifier; +727 } +728 //</editor-fold> +729 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> +730 +731 /** +732 * Standard toString() implementation. +733 * +734 * @return the string representation of the object +735 */ +736 @Override +737 public String toString() { +738 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence +739 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; +740 } +741 +742 /** +743 * Standard hashCode() implementation. +744 * +745 * @return the hashCode +746 */ +747 @Override +748 public int hashCode() { +749 int hash = 5; +750 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); +751 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); +752 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); +753 return hash; +754 } +755 +756 /** +757 * Standard equals implementation. +758 * +759 * @param obj the object to compare +760 * @return true if the objects are equal, otherwise false +761 */ +762 @Override +763 public boolean equals(Object obj) { +764 if (obj == null) { +765 return false; +766 } +767 if (getClass() != obj.getClass()) { +768 return false; 769 } -770 return conf; -771 } -772 } -773 } +770 final IdentifierMatch other = (IdentifierMatch) obj; +771 if (this.evidenceConfidence != other.evidenceConfidence) { +772 return false; +773 } +774 if (this.confidence != other.confidence) { +775 return false; +776 } +777 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { +778 return false; +779 } +780 return true; +781 } +782 //</editor-fold> +783 +784 /** +785 * Standard implementation of compareTo that compares identifier +786 * confidence, evidence confidence, and then the identifier. +787 * +788 * @param o the IdentifierMatch to compare to +789 * @return the natural ordering of IdentifierMatch +790 */ +791 @Override +792 public int compareTo(IdentifierMatch o) { +793 int conf = this.confidence.compareTo(o.confidence); +794 if (conf == 0) { +795 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); +796 if (conf == 0) { +797 conf = identifier.compareTo(o.identifier); +798 } +799 } +800 return conf; +801 } +802 } +803 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html index 6dc735f81..81b4a7155 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html @@ -49,125 +49,126 @@ 41 * 42 * @author colezlaw 43 */ -44 public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { -45 -46 /** -47 * The logger. -48 */ -49 private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class); -50 -51 /** -52 * The analyzer name. -53 */ -54 private static final String ANALYZER_NAME = "Composer.lock analyzer"; -55 -56 /** -57 * composer.json. -58 */ -59 private static final String COMPOSER_LOCK = "composer.lock"; -60 -61 /** -62 * The FileFilter. -63 */ -64 private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build(); -65 -66 /** -67 * Returns the FileFilter. -68 * -69 * @return the FileFilter -70 */ -71 @Override -72 protected FileFilter getFileFilter() { -73 return FILE_FILTER; -74 } -75 -76 /** -77 * Initializes the analyzer. -78 * -79 * @throws Exception thrown if an exception occurs getting an instance of SHA1 -80 */ -81 @Override -82 protected void initializeFileTypeAnalyzer() throws Exception { -83 sha1 = MessageDigest.getInstance("SHA1"); -84 } -85 -86 /** -87 * The MessageDigest for calculating a new digest for the new dependencies added. -88 */ -89 private MessageDigest sha1 = null; -90 -91 /** -92 * Entry point for the analyzer. -93 * -94 * @param dependency the dependency to analyze -95 * @param engine the engine scanning -96 * @throws AnalysisException if there's a failure during analysis -97 */ -98 @Override -99 protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -100 FileInputStream fis = null; -101 try { -102 fis = new FileInputStream(dependency.getActualFile()); -103 final ComposerLockParser clp = new ComposerLockParser(fis); -104 LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath()); -105 clp.process(); -106 for (ComposerDependency dep : clp.getDependencies()) { -107 final Dependency d = new Dependency(dependency.getActualFile()); -108 d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject())); -109 final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject()); -110 d.setFilePath(filePath); -111 d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset())))); -112 d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST); -113 d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST); -114 d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST); -115 LOGGER.info("Adding dependency {}", d); -116 engine.getDependencies().add(d); -117 } -118 } catch (FileNotFoundException fnfe) { -119 LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath()); -120 } catch (ComposerException ce) { -121 LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce); -122 } finally { -123 if (fis != null) { -124 try { -125 fis.close(); -126 } catch (Exception e) { -127 LOGGER.debug("Unable to close file", e); -128 } -129 } -130 } -131 } -132 -133 /** -134 * Gets the key to determine whether the analyzer is enabled. -135 * -136 * @return the key specifying whether the analyzer is enabled -137 */ -138 @Override -139 protected String getAnalyzerEnabledSettingKey() { -140 return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED; -141 } -142 -143 /** -144 * Returns the analyzer's name. -145 * -146 * @return the analyzer's name -147 */ -148 @Override -149 public String getName() { -150 return ANALYZER_NAME; -151 } -152 -153 /** -154 * Returns the phase this analyzer should run under. -155 * -156 * @return the analysis phase -157 */ -158 @Override -159 public AnalysisPhase getAnalysisPhase() { -160 return AnalysisPhase.INFORMATION_COLLECTION; -161 } -162 } +44 @Experimental +45 public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { +46 +47 /** +48 * The logger. +49 */ +50 private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class); +51 +52 /** +53 * The analyzer name. +54 */ +55 private static final String ANALYZER_NAME = "Composer.lock analyzer"; +56 +57 /** +58 * composer.json. +59 */ +60 private static final String COMPOSER_LOCK = "composer.lock"; +61 +62 /** +63 * The FileFilter. +64 */ +65 private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build(); +66 +67 /** +68 * Returns the FileFilter. +69 * +70 * @return the FileFilter +71 */ +72 @Override +73 protected FileFilter getFileFilter() { +74 return FILE_FILTER; +75 } +76 +77 /** +78 * Initializes the analyzer. +79 * +80 * @throws Exception thrown if an exception occurs getting an instance of SHA1 +81 */ +82 @Override +83 protected void initializeFileTypeAnalyzer() throws Exception { +84 sha1 = MessageDigest.getInstance("SHA1"); +85 } +86 +87 /** +88 * The MessageDigest for calculating a new digest for the new dependencies added. +89 */ +90 private MessageDigest sha1 = null; +91 +92 /** +93 * Entry point for the analyzer. +94 * +95 * @param dependency the dependency to analyze +96 * @param engine the engine scanning +97 * @throws AnalysisException if there's a failure during analysis +98 */ +99 @Override +100 protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +101 FileInputStream fis = null; +102 try { +103 fis = new FileInputStream(dependency.getActualFile()); +104 final ComposerLockParser clp = new ComposerLockParser(fis); +105 LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath()); +106 clp.process(); +107 for (ComposerDependency dep : clp.getDependencies()) { +108 final Dependency d = new Dependency(dependency.getActualFile()); +109 d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject())); +110 final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject()); +111 d.setFilePath(filePath); +112 d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset())))); +113 d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST); +114 d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST); +115 d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST); +116 LOGGER.info("Adding dependency {}", d); +117 engine.getDependencies().add(d); +118 } +119 } catch (FileNotFoundException fnfe) { +120 LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath()); +121 } catch (ComposerException ce) { +122 LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce); +123 } finally { +124 if (fis != null) { +125 try { +126 fis.close(); +127 } catch (Exception e) { +128 LOGGER.debug("Unable to close file", e); +129 } +130 } +131 } +132 } +133 +134 /** +135 * Gets the key to determine whether the analyzer is enabled. +136 * +137 * @return the key specifying whether the analyzer is enabled +138 */ +139 @Override +140 protected String getAnalyzerEnabledSettingKey() { +141 return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED; +142 } +143 +144 /** +145 * Returns the analyzer's name. +146 * +147 * @return the analyzer's name +148 */ +149 @Override +150 public String getName() { +151 return ANALYZER_NAME; +152 } +153 +154 /** +155 * Returns the phase this analyzer should run under. +156 * +157 * @return the analysis phase +158 */ +159 @Override +160 public AnalysisPhase getAnalysisPhase() { +161 return AnalysisPhase.INFORMATION_COLLECTION; +162 } +163 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html index b822a93c1..b8b973dd7 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html @@ -43,397 +43,475 @@ 35 36 /** 37 * <p> -38 * This analyzer ensures dependencies that should be grouped together, to remove excess noise from the report, are grouped. An -39 * example would be Spring, Spring Beans, Spring MVC, etc. If they are all for the same version and have the same relative path -40 * then these should be grouped into a single dependency under the core/main library.</p> -41 * <p> -42 * Note, this grouping only works on dependencies with identified CVE entries</p> -43 * -44 * @author Jeremy Long -45 */ -46 public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer { -47 -48 /** -49 * The Logger. -50 */ -51 private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class); -52 -53 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> -54 /** -55 * A pattern for obtaining the first part of a filename. -56 */ -57 private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*"); -58 /** -59 * a flag indicating if this analyzer has run. This analyzer only runs once. -60 */ -61 private boolean analyzed = false; -62 //</editor-fold> -63 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -64 /** -65 * The name of the analyzer. -66 */ -67 private static final String ANALYZER_NAME = "Dependency Bundling Analyzer"; -68 /** -69 * The phase that this analyzer is intended to run in. -70 */ -71 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS; -72 -73 /** -74 * Returns the name of the analyzer. -75 * -76 * @return the name of the analyzer. -77 */ -78 @Override -79 public String getName() { -80 return ANALYZER_NAME; -81 } -82 -83 /** -84 * Returns the phase that the analyzer is intended to run in. -85 * -86 * @return the phase that the analyzer is intended to run in. -87 */ -88 @Override -89 public AnalysisPhase getAnalysisPhase() { -90 return ANALYSIS_PHASE; -91 } -92 //</editor-fold> -93 -94 /** -95 * Analyzes a set of dependencies. If they have been found to have the same base path and the same set of identifiers they are -96 * likely related. The related dependencies are bundled into a single reportable item. -97 * -98 * @param ignore this analyzer ignores the dependency being analyzed -99 * @param engine the engine that is scanning the dependencies -100 * @throws AnalysisException is thrown if there is an error reading the JAR file. -101 */ -102 @Override -103 public void analyze(Dependency ignore, Engine engine) throws AnalysisException { -104 if (!analyzed) { -105 analyzed = true; -106 final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>(); -107 final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator(); -108 //for (Dependency nextDependency : engine.getDependencies()) { -109 while (mainIterator.hasNext()) { -110 final Dependency dependency = mainIterator.next(); -111 if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) { -112 final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex()); -113 while (subIterator.hasNext()) { -114 final Dependency nextDependency = subIterator.next(); -115 if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath()) -116 && !containedInWar(nextDependency.getFilePath())) { -117 if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) { -118 mergeDependencies(dependency, nextDependency, dependenciesToRemove); -119 } else { -120 mergeDependencies(nextDependency, dependency, dependenciesToRemove); -121 break; //since we merged into the next dependency - skip forward to the next in mainIterator -122 } -123 } else if (isShadedJar(dependency, nextDependency)) { -124 if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) { +38 * This analyzer ensures dependencies that should be grouped together, to remove +39 * excess noise from the report, are grouped. An example would be Spring, Spring +40 * Beans, Spring MVC, etc. If they are all for the same version and have the +41 * same relative path then these should be grouped into a single dependency +42 * under the core/main library.</p> +43 * <p> +44 * Note, this grouping only works on dependencies with identified CVE +45 * entries</p> +46 * +47 * @author Jeremy Long +48 */ +49 public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer { +50 +51 /** +52 * The Logger. +53 */ +54 private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class); +55 +56 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> +57 /** +58 * A pattern for obtaining the first part of a filename. +59 */ +60 private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*"); +61 /** +62 * a flag indicating if this analyzer has run. This analyzer only runs once. +63 */ +64 private boolean analyzed = false; +65 //</editor-fold> +66 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +67 /** +68 * The name of the analyzer. +69 */ +70 private static final String ANALYZER_NAME = "Dependency Bundling Analyzer"; +71 /** +72 * The phase that this analyzer is intended to run in. +73 */ +74 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS; +75 +76 /** +77 * Returns the name of the analyzer. +78 * +79 * @return the name of the analyzer. +80 */ +81 @Override +82 public String getName() { +83 return ANALYZER_NAME; +84 } +85 +86 /** +87 * Returns the phase that the analyzer is intended to run in. +88 * +89 * @return the phase that the analyzer is intended to run in. +90 */ +91 @Override +92 public AnalysisPhase getAnalysisPhase() { +93 return ANALYSIS_PHASE; +94 } +95 //</editor-fold> +96 +97 /** +98 * Analyzes a set of dependencies. If they have been found to have the same +99 * base path and the same set of identifiers they are likely related. The +100 * related dependencies are bundled into a single reportable item. +101 * +102 * @param ignore this analyzer ignores the dependency being analyzed +103 * @param engine the engine that is scanning the dependencies +104 * @throws AnalysisException is thrown if there is an error reading the JAR +105 * file. +106 */ +107 @Override +108 public void analyze(Dependency ignore, Engine engine) throws AnalysisException { +109 if (!analyzed) { +110 analyzed = true; +111 final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>(); +112 final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator(); +113 //for (Dependency nextDependency : engine.getDependencies()) { +114 while (mainIterator.hasNext()) { +115 final Dependency dependency = mainIterator.next(); +116 if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) { +117 final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex()); +118 while (subIterator.hasNext()) { +119 final Dependency nextDependency = subIterator.next(); +120 if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath()) +121 && !containedInWar(nextDependency.getFilePath())) { +122 if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) { +123 mergeDependencies(dependency, nextDependency, dependenciesToRemove); +124 } else { 125 mergeDependencies(nextDependency, dependency, dependenciesToRemove); -126 nextDependency.getRelatedDependencies().remove(dependency); -127 break; -128 } else { -129 mergeDependencies(dependency, nextDependency, dependenciesToRemove); -130 dependency.getRelatedDependencies().remove(nextDependency); -131 } -132 } else if (cpeIdentifiersMatch(dependency, nextDependency) -133 && hasSameBasePath(dependency, nextDependency) -134 && fileNameMatch(dependency, nextDependency)) { -135 if (isCore(dependency, nextDependency)) { -136 mergeDependencies(dependency, nextDependency, dependenciesToRemove); -137 } else { -138 mergeDependencies(nextDependency, dependency, dependenciesToRemove); -139 break; //since we merged into the next dependency - skip forward to the next in mainIterator -140 } -141 } -142 } -143 } -144 } -145 //removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions -146 // was difficult because of the inner iterator. -147 engine.getDependencies().removeAll(dependenciesToRemove); -148 } -149 } -150 -151 /** -152 * Adds the relatedDependency to the dependency's related dependencies. -153 * -154 * @param dependency the main dependency -155 * @param relatedDependency a collection of dependencies to be removed from the main analysis loop, this is the source of -156 * dependencies to remove -157 * @param dependenciesToRemove a collection of dependencies that will be removed from the main analysis loop, this function -158 * adds to this collection -159 */ -160 private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) { -161 dependency.addRelatedDependency(relatedDependency); -162 final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator(); -163 while (i.hasNext()) { -164 dependency.addRelatedDependency(i.next()); -165 i.remove(); -166 } -167 if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) { -168 dependency.addAllProjectReferences(relatedDependency.getProjectReferences()); -169 } -170 dependenciesToRemove.add(relatedDependency); -171 } -172 -173 /** -174 * Attempts to trim a maven repo to a common base path. This is typically [drive]\[repo_location]\repository\[path1]\[path2]. -175 * -176 * @param path the path to trim -177 * @return a string representing the base path. -178 */ -179 private String getBaseRepoPath(final String path) { -180 int pos = path.indexOf("repository" + File.separator) + 11; -181 if (pos < 0) { -182 return path; +126 break; //since we merged into the next dependency - skip forward to the next in mainIterator +127 } +128 } else if (isShadedJar(dependency, nextDependency)) { +129 if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) { +130 mergeDependencies(nextDependency, dependency, dependenciesToRemove); +131 nextDependency.getRelatedDependencies().remove(dependency); +132 break; +133 } else { +134 mergeDependencies(dependency, nextDependency, dependenciesToRemove); +135 dependency.getRelatedDependencies().remove(nextDependency); +136 } +137 } else if (cpeIdentifiersMatch(dependency, nextDependency) +138 && hasSameBasePath(dependency, nextDependency) +139 && fileNameMatch(dependency, nextDependency)) { +140 if (isCore(dependency, nextDependency)) { +141 mergeDependencies(dependency, nextDependency, dependenciesToRemove); +142 } else { +143 mergeDependencies(nextDependency, dependency, dependenciesToRemove); +144 break; //since we merged into the next dependency - skip forward to the next in mainIterator +145 } +146 } else if (isSameRubyGem(dependency, nextDependency)) { +147 final Dependency main = getMainGemspecDependency(dependency, nextDependency); +148 if (main == dependency) { +149 mergeDependencies(dependency, nextDependency, dependenciesToRemove); +150 } else { +151 mergeDependencies(nextDependency, dependency, dependenciesToRemove); +152 break; //since we merged into the next dependency - skip forward to the next in mainIterator +153 } +154 } +155 } +156 } +157 } +158 //removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions +159 // was difficult because of the inner iterator. +160 engine.getDependencies().removeAll(dependenciesToRemove); +161 } +162 } +163 +164 /** +165 * Adds the relatedDependency to the dependency's related dependencies. +166 * +167 * @param dependency the main dependency +168 * @param relatedDependency a collection of dependencies to be removed from +169 * the main analysis loop, this is the source of dependencies to remove +170 * @param dependenciesToRemove a collection of dependencies that will be +171 * removed from the main analysis loop, this function adds to this +172 * collection +173 */ +174 private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) { +175 dependency.addRelatedDependency(relatedDependency); +176 final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator(); +177 while (i.hasNext()) { +178 dependency.addRelatedDependency(i.next()); +179 i.remove(); +180 } +181 if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) { +182 dependency.addAllProjectReferences(relatedDependency.getProjectReferences()); 183 } -184 int tmp = path.indexOf(File.separator, pos); -185 if (tmp <= 0) { -186 return path; -187 } -188 if (tmp > 0) { -189 pos = tmp + 1; -190 } -191 tmp = path.indexOf(File.separator, pos); -192 if (tmp > 0) { -193 pos = tmp + 1; -194 } -195 return path.substring(0, pos); -196 } -197 -198 /** -199 * Returns true if the file names (and version if it exists) of the two dependencies are sufficiently similar. -200 * -201 * @param dependency1 a dependency2 to compare -202 * @param dependency2 a dependency2 to compare -203 * @return true if the identifiers in the two supplied dependencies are equal -204 */ -205 private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) { -206 if (dependency1 == null || dependency1.getFileName() == null -207 || dependency2 == null || dependency2.getFileName() == null) { -208 return false; +184 dependenciesToRemove.add(relatedDependency); +185 } +186 +187 /** +188 * Attempts to trim a maven repo to a common base path. This is typically +189 * [drive]\[repo_location]\repository\[path1]\[path2]. +190 * +191 * @param path the path to trim +192 * @return a string representing the base path. +193 */ +194 private String getBaseRepoPath(final String path) { +195 int pos = path.indexOf("repository" + File.separator) + 11; +196 if (pos < 0) { +197 return path; +198 } +199 int tmp = path.indexOf(File.separator, pos); +200 if (tmp <= 0) { +201 return path; +202 } +203 if (tmp > 0) { +204 pos = tmp + 1; +205 } +206 tmp = path.indexOf(File.separator, pos); +207 if (tmp > 0) { +208 pos = tmp + 1; 209 } -210 final String fileName1 = dependency1.getActualFile().getName(); -211 final String fileName2 = dependency2.getActualFile().getName(); +210 return path.substring(0, pos); +211 } 212 -213 //version check -214 final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1); -215 final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2); -216 if (version1 != null && version2 != null && !version1.equals(version2)) { -217 return false; -218 } -219 -220 //filename check -221 final Matcher match1 = STARTING_TEXT_PATTERN.matcher(fileName1); -222 final Matcher match2 = STARTING_TEXT_PATTERN.matcher(fileName2); -223 if (match1.find() && match2.find()) { -224 return match1.group().equals(match2.group()); -225 } -226 -227 return false; -228 } +213 /** +214 * Returns true if the file names (and version if it exists) of the two +215 * dependencies are sufficiently similar. +216 * +217 * @param dependency1 a dependency2 to compare +218 * @param dependency2 a dependency2 to compare +219 * @return true if the identifiers in the two supplied dependencies are +220 * equal +221 */ +222 private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) { +223 if (dependency1 == null || dependency1.getFileName() == null +224 || dependency2 == null || dependency2.getFileName() == null) { +225 return false; +226 } +227 final String fileName1 = dependency1.getActualFile().getName(); +228 final String fileName2 = dependency2.getActualFile().getName(); 229 -230 /** -231 * Returns true if the CPE identifiers in the two supplied dependencies are equal. -232 * -233 * @param dependency1 a dependency2 to compare -234 * @param dependency2 a dependency2 to compare -235 * @return true if the identifiers in the two supplied dependencies are equal -236 */ -237 private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) { -238 if (dependency1 == null || dependency1.getIdentifiers() == null -239 || dependency2 == null || dependency2.getIdentifiers() == null) { -240 return false; -241 } -242 boolean matches = false; -243 int cpeCount1 = 0; -244 int cpeCount2 = 0; -245 for (Identifier i : dependency1.getIdentifiers()) { -246 if ("cpe".equals(i.getType())) { -247 cpeCount1 += 1; -248 } -249 } -250 for (Identifier i : dependency2.getIdentifiers()) { -251 if ("cpe".equals(i.getType())) { -252 cpeCount2 += 1; -253 } -254 } -255 if (cpeCount1 > 0 && cpeCount1 == cpeCount2) { -256 for (Identifier i : dependency1.getIdentifiers()) { -257 if ("cpe".equals(i.getType())) { -258 matches |= dependency2.getIdentifiers().contains(i); -259 if (!matches) { -260 break; -261 } -262 } -263 } -264 } -265 LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName()); -266 return matches; -267 } -268 -269 /** -270 * Determines if the two dependencies have the same base path. -271 * -272 * @param dependency1 a Dependency object -273 * @param dependency2 a Dependency object -274 * @return true if the base paths of the dependencies are identical -275 */ -276 private boolean hasSameBasePath(Dependency dependency1, Dependency dependency2) { -277 if (dependency1 == null || dependency2 == null) { -278 return false; -279 } -280 final File lFile = new File(dependency1.getFilePath()); -281 String left = lFile.getParent(); -282 final File rFile = new File(dependency2.getFilePath()); -283 String right = rFile.getParent(); -284 if (left == null) { -285 return right == null; -286 } -287 if (left.equalsIgnoreCase(right)) { -288 return true; -289 } -290 if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) { -291 left = getBaseRepoPath(left); -292 right = getBaseRepoPath(right); -293 } -294 if (left.equalsIgnoreCase(right)) { -295 return true; -296 } -297 //new code -298 for (Dependency child : dependency2.getRelatedDependencies()) { -299 if (hasSameBasePath(dependency1, child)) { -300 return true; -301 } -302 } -303 return false; -304 } -305 -306 /** -307 * This is likely a very broken attempt at determining if the 'left' dependency is the 'core' library in comparison to the -308 * 'right' library. -309 * -310 * @param left the dependency to test -311 * @param right the dependency to test against -312 * @return a boolean indicating whether or not the left dependency should be considered the "core" version. -313 */ -314 boolean isCore(Dependency left, Dependency right) { -315 final String leftName = left.getFileName().toLowerCase(); -316 final String rightName = right.getFileName().toLowerCase(); -317 -318 final boolean returnVal; -319 if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") -320 || rightName.contains("core") && !leftName.contains("core") -321 || rightName.contains("kernel") && !leftName.contains("kernel")) { -322 returnVal = false; -323 } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") -324 || !rightName.contains("core") && leftName.contains("core") -325 || !rightName.contains("kernel") && leftName.contains("kernel")) { -326 returnVal = true; -327 // } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) { -328 // returnVal = true; -329 // } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) { -330 // returnVal = false; -331 } else { -332 /* -333 * considered splitting the names up and comparing the components, -334 * but decided that the file name length should be sufficient as the -335 * "core" component, if this follows a normal naming protocol should -336 * be shorter: -337 * axis2-saaj-1.4.1.jar -338 * axis2-1.4.1.jar <----- -339 * axis2-kernel-1.4.1.jar -340 */ -341 returnVal = leftName.length() <= rightName.length(); +230 //version check +231 final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1); +232 final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2); +233 if (version1 != null && version2 != null && !version1.equals(version2)) { +234 return false; +235 } +236 +237 //filename check +238 final Matcher match1 = STARTING_TEXT_PATTERN.matcher(fileName1); +239 final Matcher match2 = STARTING_TEXT_PATTERN.matcher(fileName2); +240 if (match1.find() && match2.find()) { +241 return match1.group().equals(match2.group()); +242 } +243 +244 return false; +245 } +246 +247 /** +248 * Returns true if the CPE identifiers in the two supplied dependencies are +249 * equal. +250 * +251 * @param dependency1 a dependency2 to compare +252 * @param dependency2 a dependency2 to compare +253 * @return true if the identifiers in the two supplied dependencies are +254 * equal +255 */ +256 private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) { +257 if (dependency1 == null || dependency1.getIdentifiers() == null +258 || dependency2 == null || dependency2.getIdentifiers() == null) { +259 return false; +260 } +261 boolean matches = false; +262 int cpeCount1 = 0; +263 int cpeCount2 = 0; +264 for (Identifier i : dependency1.getIdentifiers()) { +265 if ("cpe".equals(i.getType())) { +266 cpeCount1 += 1; +267 } +268 } +269 for (Identifier i : dependency2.getIdentifiers()) { +270 if ("cpe".equals(i.getType())) { +271 cpeCount2 += 1; +272 } +273 } +274 if (cpeCount1 > 0 && cpeCount1 == cpeCount2) { +275 for (Identifier i : dependency1.getIdentifiers()) { +276 if ("cpe".equals(i.getType())) { +277 matches |= dependency2.getIdentifiers().contains(i); +278 if (!matches) { +279 break; +280 } +281 } +282 } +283 } +284 LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName()); +285 return matches; +286 } +287 +288 /** +289 * Determines if the two dependencies have the same base path. +290 * +291 * @param dependency1 a Dependency object +292 * @param dependency2 a Dependency object +293 * @return true if the base paths of the dependencies are identical +294 */ +295 private boolean hasSameBasePath(Dependency dependency1, Dependency dependency2) { +296 if (dependency1 == null || dependency2 == null) { +297 return false; +298 } +299 final File lFile = new File(dependency1.getFilePath()); +300 String left = lFile.getParent(); +301 final File rFile = new File(dependency2.getFilePath()); +302 String right = rFile.getParent(); +303 if (left == null) { +304 return right == null; +305 } +306 if (left.equalsIgnoreCase(right)) { +307 return true; +308 } +309 if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) { +310 left = getBaseRepoPath(left); +311 right = getBaseRepoPath(right); +312 } +313 if (left.equalsIgnoreCase(right)) { +314 return true; +315 } +316 //new code +317 for (Dependency child : dependency2.getRelatedDependencies()) { +318 if (hasSameBasePath(dependency1, child)) { +319 return true; +320 } +321 } +322 return false; +323 } +324 +325 /** +326 * Bundling Ruby gems that are identified from different .gemspec files but +327 * denote the same package path. This happens when Ruby bundler installs an +328 * application's dependencies by running "bundle install". +329 * +330 * @param dependency1 dependency to compare +331 * @param dependency2 dependency to compare +332 * @return true if the the dependencies being analyzed appear to be the +333 * same; otherwise false +334 */ +335 private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) { +336 if (dependency1 == null || dependency2 == null +337 || !dependency1.getFileName().endsWith(".gemspec") +338 || !dependency2.getFileName().endsWith(".gemspec") +339 || dependency1.getPackagePath() == null +340 || dependency2.getPackagePath() == null) { +341 return false; 342 } -343 LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName()); -344 return returnVal; -345 } +343 if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath())) { +344 return true; +345 } 346 -347 /** -348 * Compares the SHA1 hashes of two dependencies to determine if they are equal. -349 * -350 * @param dependency1 a dependency object to compare -351 * @param dependency2 a dependency object to compare -352 * @return true if the sha1 hashes of the two dependencies match; otherwise false -353 */ -354 private boolean hashesMatch(Dependency dependency1, Dependency dependency2) { -355 if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) { -356 return false; -357 } -358 return dependency1.getSha1sum().equals(dependency2.getSha1sum()); -359 } -360 -361 /** -362 * Determines if the jar is shaded and the created pom.xml identified the same CPE as the jar - if so, the pom.xml dependency -363 * should be removed. -364 * -365 * @param dependency a dependency to check -366 * @param nextDependency another dependency to check -367 * @return true if on of the dependencies is a pom.xml and the identifiers between the two collections match; otherwise false -368 */ -369 private boolean isShadedJar(Dependency dependency, Dependency nextDependency) { -370 final String mainName = dependency.getFileName().toLowerCase(); -371 final String nextName = nextDependency.getFileName().toLowerCase(); -372 if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) { -373 return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers()); -374 } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) { -375 return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers()); -376 } -377 return false; -378 } -379 -380 /** -381 * Determines which path is shortest; if path lengths are equal then we use compareTo of the string method to determine if the -382 * first path is smaller. -383 * -384 * @param left the first path to compare -385 * @param right the second path to compare -386 * @return <code>true</code> if the leftPath is the shortest; otherwise <code>false</code> +347 return false; +348 } +349 +350 /** +351 * Ruby gems installed by "bundle install" can have zero or more *.gemspec +352 * files, all of which have the same packagePath and should be grouped. If +353 * one of these gemspec is from <parent>/specifications/*.gemspec, because +354 * it is a stub with fully resolved gem meta-data created by Ruby bundler, +355 * this dependency should be the main one. Otherwise, use dependency2 as +356 * main. +357 * +358 * This method returns null if any dependency is not from *.gemspec, or the +359 * two do not have the same packagePath. In this case, they should not be +360 * grouped. +361 * +362 * @param dependency1 dependency to compare +363 * @param dependency2 dependency to compare +364 * @return the main dependency; or null if a gemspec is not included in the +365 * analysis +366 */ +367 private Dependency getMainGemspecDependency(Dependency dependency1, Dependency dependency2) { +368 if (isSameRubyGem(dependency1, dependency2)) { +369 final File lFile = dependency1.getActualFile(); +370 final File left = lFile.getParentFile(); +371 if (left != null && left.getName().equalsIgnoreCase("specifications")) { +372 return dependency1; +373 } +374 return dependency2; +375 } +376 return null; +377 } +378 +379 /** +380 * This is likely a very broken attempt at determining if the 'left' +381 * dependency is the 'core' library in comparison to the 'right' library. +382 * +383 * @param left the dependency to test +384 * @param right the dependency to test against +385 * @return a boolean indicating whether or not the left dependency should be +386 * considered the "core" version. 387 */ -388 protected boolean firstPathIsShortest(String left, String right) { -389 final String leftPath = left.replace('\\', '/'); -390 final String rightPath = right.replace('\\', '/'); +388 boolean isCore(Dependency left, Dependency right) { +389 final String leftName = left.getFileName().toLowerCase(); +390 final String rightName = right.getFileName().toLowerCase(); 391 -392 final int leftCount = countChar(leftPath, '/'); -393 final int rightCount = countChar(rightPath, '/'); -394 if (leftCount == rightCount) { -395 return leftPath.compareTo(rightPath) <= 0; -396 } else { -397 return leftCount < rightCount; -398 } -399 } -400 -401 /** -402 * Counts the number of times the character is present in the string. -403 * -404 * @param string the string to count the characters in -405 * @param c the character to count -406 * @return the number of times the character is present in the string -407 */ -408 private int countChar(String string, char c) { -409 int count = 0; -410 final int max = string.length(); -411 for (int i = 0; i < max; i++) { -412 if (c == string.charAt(i)) { -413 count++; -414 } -415 } -416 return count; -417 } -418 -419 /** -420 * Checks if the given file path is contained within a war or ear file. -421 * -422 * @param filePath the file path to check -423 * @return true if the path contains '.war\' or '.ear\'. -424 */ -425 private boolean containedInWar(String filePath) { -426 return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*"); -427 } -428 } +392 final boolean returnVal; +393 if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") +394 || rightName.contains("core") && !leftName.contains("core") +395 || rightName.contains("kernel") && !leftName.contains("kernel")) { +396 returnVal = false; +397 } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") +398 || !rightName.contains("core") && leftName.contains("core") +399 || !rightName.contains("kernel") && leftName.contains("kernel")) { +400 returnVal = true; +401 // } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) { +402 // returnVal = true; +403 // } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) { +404 // returnVal = false; +405 } else { +406 /* +407 * considered splitting the names up and comparing the components, +408 * but decided that the file name length should be sufficient as the +409 * "core" component, if this follows a normal naming protocol should +410 * be shorter: +411 * axis2-saaj-1.4.1.jar +412 * axis2-1.4.1.jar <----- +413 * axis2-kernel-1.4.1.jar +414 */ +415 returnVal = leftName.length() <= rightName.length(); +416 } +417 LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName()); +418 return returnVal; +419 } +420 +421 /** +422 * Compares the SHA1 hashes of two dependencies to determine if they are +423 * equal. +424 * +425 * @param dependency1 a dependency object to compare +426 * @param dependency2 a dependency object to compare +427 * @return true if the sha1 hashes of the two dependencies match; otherwise +428 * false +429 */ +430 private boolean hashesMatch(Dependency dependency1, Dependency dependency2) { +431 if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) { +432 return false; +433 } +434 return dependency1.getSha1sum().equals(dependency2.getSha1sum()); +435 } +436 +437 /** +438 * Determines if the jar is shaded and the created pom.xml identified the +439 * same CPE as the jar - if so, the pom.xml dependency should be removed. +440 * +441 * @param dependency a dependency to check +442 * @param nextDependency another dependency to check +443 * @return true if on of the dependencies is a pom.xml and the identifiers +444 * between the two collections match; otherwise false +445 */ +446 private boolean isShadedJar(Dependency dependency, Dependency nextDependency) { +447 final String mainName = dependency.getFileName().toLowerCase(); +448 final String nextName = nextDependency.getFileName().toLowerCase(); +449 if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) { +450 return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers()); +451 } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) { +452 return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers()); +453 } +454 return false; +455 } +456 +457 /** +458 * Determines which path is shortest; if path lengths are equal then we use +459 * compareTo of the string method to determine if the first path is smaller. +460 * +461 * @param left the first path to compare +462 * @param right the second path to compare +463 * @return <code>true</code> if the leftPath is the shortest; otherwise +464 * <code>false</code> +465 */ +466 protected boolean firstPathIsShortest(String left, String right) { +467 final String leftPath = left.replace('\\', '/'); +468 final String rightPath = right.replace('\\', '/'); +469 +470 final int leftCount = countChar(leftPath, '/'); +471 final int rightCount = countChar(rightPath, '/'); +472 if (leftCount == rightCount) { +473 return leftPath.compareTo(rightPath) <= 0; +474 } else { +475 return leftCount < rightCount; +476 } +477 } +478 +479 /** +480 * Counts the number of times the character is present in the string. +481 * +482 * @param string the string to count the characters in +483 * @param c the character to count +484 * @return the number of times the character is present in the string +485 */ +486 private int countChar(String string, char c) { +487 int count = 0; +488 final int max = string.length(); +489 for (int i = 0; i < max; i++) { +490 if (c == string.charAt(i)) { +491 count++; +492 } +493 } +494 return count; +495 } +496 +497 /** +498 * Checks if the given file path is contained within a war or ear file. +499 * +500 * @param filePath the file path to check +501 * @return true if the path contains '.war\' or '.ear\'. +502 */ +503 private boolean containedInWar(String filePath) { +504 return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*"); +505 } +506 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/Experimental.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/Experimental.html new file mode 100644 index 000000000..98b6949ac --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/Experimental.html @@ -0,0 +1,47 @@ + + + +Experimental xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +3    *
      +4    * Licensed under the Apache License, Version 2.0 (the "License");
      +5    * you may not use this file except in compliance with the License.
      +6    * You may obtain a copy of the License at
      +7    *
      +8    *     http://www.apache.org/licenses/LICENSE-2.0
      +9    *
      +10   * Unless required by applicable law or agreed to in writing, software
      +11   * distributed under the License is distributed on an "AS IS" BASIS,
      +12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      +13   * See the License for the specific language governing permissions and
      +14   * limitations under the License.
      +15   *
      +16   * Copyright (c) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.analyzer;
      +19  
      +20  import java.lang.annotation.ElementType;
      +21  import java.lang.annotation.Retention;
      +22  import java.lang.annotation.RetentionPolicy;
      +23  import java.lang.annotation.Target;
      +24  
      +25  /**
      +26   * Annotation used to flag an analyzer as experimental.
      +27   *
      +28   * @author jeremy long
      +29   */
      +30  @Retention(RetentionPolicy.RUNTIME)
      +31  @Target(ElementType.TYPE)
      +32  public @interface Experimental {
      +33  
      +34  }
      +
      +
      + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.html index 6d2cc1c4f..623b7e3ac 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.html @@ -75,58 +75,55 @@ 67 } 68 //</editor-fold> 69 -70 // Python init files -71 private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[] { -72 "__init__.py", -73 "__init__.pyc", -74 "__init__.pyo" -75 }); -76 -77 /** -78 * Collects information about the file name. -79 * -80 * @param dependency the dependency to analyze. -81 * @param engine the engine that is scanning the dependencies -82 * @throws AnalysisException is thrown if there is an error reading the JAR file. -83 */ -84 @Override -85 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -86 -87 //strip any path information that may get added by ArchiveAnalyzer, etc. -88 final File f = dependency.getActualFile(); -89 final String fileName = FilenameUtils.removeExtension(f.getName()); -90 -91 //add version evidence -92 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName); -93 if (version != null) { -94 // If the version number is just a number like 2 or 23, reduce the confidence -95 // a shade. This should hopefully correct for cases like log4j.jar or -96 // struts2-core.jar -97 if (version.getVersionParts() == null || version.getVersionParts().size() < 2) { -98 dependency.getVersionEvidence().addEvidence("file", "name", -99 version.toString(), Confidence.MEDIUM); -100 } else { +70 /** +71 * Python init files +72 */ +73 private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{ +74 "__init__.py", +75 "__init__.pyc", +76 "__init__.pyo", +77 }); +78 +79 /** +80 * Collects information about the file name. +81 * +82 * @param dependency the dependency to analyze. +83 * @param engine the engine that is scanning the dependencies +84 * @throws AnalysisException is thrown if there is an error reading the JAR +85 * file. +86 */ +87 @Override +88 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +89 +90 //strip any path information that may get added by ArchiveAnalyzer, etc. +91 final File f = dependency.getActualFile(); +92 final String fileName = FilenameUtils.removeExtension(f.getName()); +93 +94 //add version evidence +95 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName); +96 if (version != null) { +97 // If the version number is just a number like 2 or 23, reduce the confidence +98 // a shade. This should hopefully correct for cases like log4j.jar or +99 // struts2-core.jar +100 if (version.getVersionParts() == null || version.getVersionParts().size() < 2) { 101 dependency.getVersionEvidence().addEvidence("file", "name", -102 version.toString(), Confidence.HIGHEST); -103 } -104 dependency.getVersionEvidence().addEvidence("file", "name", -105 fileName, Confidence.MEDIUM); -106 } -107 -108 //add as vendor and product evidence -109 if (fileName.contains("-")) { -110 dependency.getProductEvidence().addEvidence("file", "name", -111 fileName, Confidence.HIGHEST); -112 dependency.getVendorEvidence().addEvidence("file", "name", -113 fileName, Confidence.HIGHEST); -114 } else if (!IGNORED_FILES.accept(f)) { -115 dependency.getProductEvidence().addEvidence("file", "name", -116 fileName, Confidence.HIGH); -117 dependency.getVendorEvidence().addEvidence("file", "name", -118 fileName, Confidence.HIGH); -119 } -120 } -121 } +102 version.toString(), Confidence.MEDIUM); +103 } else { +104 dependency.getVersionEvidence().addEvidence("file", "version", +105 version.toString(), Confidence.HIGHEST); +106 } +107 dependency.getVersionEvidence().addEvidence("file", "name", +108 fileName, Confidence.MEDIUM); +109 } +110 +111 if (!IGNORED_FILES.accept(f)) { +112 dependency.getProductEvidence().addEvidence("file", "name", +113 fileName, Confidence.HIGH); +114 dependency.getVendorEvidence().addEvidence("file", "name", +115 fileName, Confidence.HIGH); +116 } +117 } +118 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html index b4316c471..973da820f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html @@ -37,38 +37,38 @@ 29 import java.util.Collections; 30 import java.util.Enumeration; 31 import java.util.HashMap; -32 import java.util.Iterator; -33 import java.util.List; -34 import java.util.Map; -35 import java.util.Map.Entry; -36 import java.util.Properties; -37 import java.util.Set; -38 import java.util.StringTokenizer; -39 import java.util.jar.Attributes; -40 import java.util.jar.JarEntry; -41 import java.util.jar.JarFile; -42 import java.util.jar.Manifest; -43 import java.util.regex.Pattern; -44 import java.util.zip.ZipEntry; -45 import org.apache.commons.compress.utils.IOUtils; -46 import org.apache.commons.io.FilenameUtils; -47 import org.jsoup.Jsoup; -48 import org.owasp.dependencycheck.Engine; -49 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -50 import org.owasp.dependencycheck.dependency.Confidence; -51 import org.owasp.dependencycheck.dependency.Dependency; -52 import org.owasp.dependencycheck.dependency.EvidenceCollection; -53 import org.owasp.dependencycheck.utils.FileFilterBuilder; -54 import org.owasp.dependencycheck.xml.pom.License; -55 import org.owasp.dependencycheck.xml.pom.PomUtils; -56 import org.owasp.dependencycheck.xml.pom.Model; -57 import org.owasp.dependencycheck.utils.FileUtils; -58 import org.owasp.dependencycheck.utils.Settings; -59 import org.slf4j.Logger; -60 import org.slf4j.LoggerFactory; -61 -62 /** -63 * Used to load a JAR file and collect information that can be used to determine the associated CPE. +32 import java.util.List; +33 import java.util.Map; +34 import java.util.Map.Entry; +35 import java.util.Properties; +36 import java.util.Set; +37 import java.util.StringTokenizer; +38 import java.util.jar.Attributes; +39 import java.util.jar.JarEntry; +40 import java.util.jar.JarFile; +41 import java.util.jar.Manifest; +42 import java.util.regex.Pattern; +43 import java.util.zip.ZipEntry; +44 import org.apache.commons.compress.utils.IOUtils; +45 import org.apache.commons.io.FilenameUtils; +46 import org.jsoup.Jsoup; +47 import org.owasp.dependencycheck.Engine; +48 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +49 import org.owasp.dependencycheck.dependency.Confidence; +50 import org.owasp.dependencycheck.dependency.Dependency; +51 import org.owasp.dependencycheck.dependency.EvidenceCollection; +52 import org.owasp.dependencycheck.utils.FileFilterBuilder; +53 import org.owasp.dependencycheck.xml.pom.License; +54 import org.owasp.dependencycheck.xml.pom.PomUtils; +55 import org.owasp.dependencycheck.xml.pom.Model; +56 import org.owasp.dependencycheck.utils.FileUtils; +57 import org.owasp.dependencycheck.utils.Settings; +58 import org.slf4j.Logger; +59 import org.slf4j.LoggerFactory; +60 +61 /** +62 * Used to load a JAR file and collect information that can be used to determine +63 * the associated CPE. 64 * 65 * @author Jeremy Long 66 */ @@ -80,1132 +80,1161 @@ 72 */ 73 private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class); 74 /** -75 * The count of directories created during analysis. This is used for creating temporary directories. -76 */ -77 private static int dirCount = 0; -78 /** -79 * The system independent newline character. -80 */ -81 private static final String NEWLINE = System.getProperty("line.separator"); -82 /** -83 * A list of values in the manifest to ignore as they only result in false positives. -84 */ -85 private static final Set<String> IGNORE_VALUES = newHashSet( -86 "Sun Java System Application Server"); -87 /** -88 * A list of elements in the manifest to ignore. -89 */ -90 private static final Set<String> IGNORE_KEYS = newHashSet( -91 "built-by", -92 "created-by", -93 "builtby", -94 "createdby", -95 "build-jdk", -96 "buildjdk", -97 "ant-version", -98 "antversion", -99 "dynamicimportpackage", -100 "dynamicimport-package", -101 "dynamic-importpackage", -102 "dynamic-import-package", -103 "import-package", -104 "ignore-package", -105 "export-package", -106 "importpackage", -107 "ignorepackage", -108 "exportpackage", -109 "sealed", -110 "manifest-version", -111 "archiver-version", -112 "manifestversion", -113 "archiverversion", -114 "classpath", -115 "class-path", -116 "tool", -117 "bundle-manifestversion", -118 "bundlemanifestversion", -119 "bundle-vendor", -120 "include-resource", -121 "embed-dependency", -122 "ipojo-components", -123 "ipojo-extension", -124 "eclipse-sourcereferences"); -125 /** -126 * Deprecated Jar manifest attribute, that is, nonetheless, useful for analysis. -127 */ -128 @SuppressWarnings("deprecation") -129 private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID -130 .toString(); -131 /** -132 * item in some manifest, should be considered medium confidence. -133 */ -134 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 -135 /** -136 * item in some manifest, should be considered medium confidence. -137 */ -138 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 -139 /** -140 * item in some manifest, should be considered medium confidence. -141 */ -142 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core -143 /** -144 * A pattern to detect HTML within text. -145 */ -146 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); -147 -148 //</editor-fold> -149 /** -150 * Constructs a new JarAnalyzer. -151 */ -152 public JarAnalyzer() { -153 } -154 -155 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> -156 /** -157 * The name of the analyzer. -158 */ -159 private static final String ANALYZER_NAME = "Jar Analyzer"; -160 /** -161 * The phase that this analyzer is intended to run in. -162 */ -163 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -164 /** -165 * The set of file extensions supported by this analyzer. -166 */ -167 private static final String[] EXTENSIONS = {"jar", "war"}; -168 -169 /** -170 * The file filter used to determine which files this analyzer supports. -171 */ -172 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); -173 -174 /** -175 * Returns the FileFilter. -176 * -177 * @return the FileFilter -178 */ -179 @Override -180 protected FileFilter getFileFilter() { -181 return FILTER; -182 } -183 -184 /** -185 * Returns the name of the analyzer. -186 * -187 * @return the name of the analyzer. -188 */ -189 @Override -190 public String getName() { -191 return ANALYZER_NAME; -192 } -193 -194 /** -195 * Returns the phase that the analyzer is intended to run in. -196 * -197 * @return the phase that the analyzer is intended to run in. -198 */ -199 @Override -200 public AnalysisPhase getAnalysisPhase() { -201 return ANALYSIS_PHASE; -202 } -203 //</editor-fold> -204 -205 /** -206 * Returns the key used in the properties file to reference the analyzer's enabled property. -207 * -208 * @return the analyzer's enabled property setting key -209 */ -210 @Override -211 protected String getAnalyzerEnabledSettingKey() { -212 return Settings.KEYS.ANALYZER_JAR_ENABLED; -213 } -214 -215 /** -216 * Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE -217 * information. -218 * -219 * @param dependency the dependency to analyze. -220 * @param engine the engine that is scanning the dependencies -221 * @throws AnalysisException is thrown if there is an error reading the JAR file. -222 */ -223 @Override -224 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -225 try { -226 final List<ClassNameInformation> classNames = collectClassNames(dependency); -227 final String fileName = dependency.getFileName().toLowerCase(); -228 if (classNames.isEmpty() -229 && (fileName.endsWith("-sources.jar") -230 || fileName.endsWith("-javadoc.jar") -231 || fileName.endsWith("-src.jar") -232 || fileName.endsWith("-doc.jar"))) { -233 engine.getDependencies().remove(dependency); -234 } -235 final boolean hasManifest = parseManifest(dependency, classNames); -236 final boolean hasPOM = analyzePOM(dependency, classNames, engine); -237 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); -238 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); -239 } catch (IOException ex) { -240 throw new AnalysisException("Exception occurred reading the JAR file.", ex); -241 } -242 } -243 -244 /** -245 * Attempts to find a pom.xml within the JAR file. If found it extracts information and adds it to the evidence. This will -246 * attempt to interpolate the strings contained within the pom.properties if one exists. -247 * -248 * @param dependency the dependency being analyzed -249 * @param classes a collection of class name information -250 * @param engine the analysis engine, used to add additional dependencies -251 * @throws AnalysisException is thrown if there is an exception parsing the pom -252 * @return whether or not evidence was added to the dependency -253 */ -254 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { -255 boolean foundSomething = false; -256 final JarFile jar; -257 try { -258 jar = new JarFile(dependency.getActualFilePath()); -259 } catch (IOException ex) { -260 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath()); -261 LOGGER.trace("", ex); -262 return false; -263 } -264 List<String> pomEntries; -265 try { -266 pomEntries = retrievePomListing(jar); -267 } catch (IOException ex) { -268 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath()); -269 LOGGER.trace("", ex); -270 return false; -271 } -272 File externalPom = null; -273 if (pomEntries.isEmpty()) { -274 final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom"; -275 externalPom = new File(pomPath); -276 if (externalPom.isFile()) { -277 pomEntries.add(pomPath); -278 } else { -279 return false; -280 } -281 } -282 for (String path : pomEntries) { -283 LOGGER.debug("Reading pom entry: {}", path); -284 Properties pomProperties = null; -285 try { -286 if (externalPom == null) { -287 pomProperties = retrievePomProperties(path, jar); -288 } -289 } catch (IOException ex) { -290 LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex); -291 } -292 Model pom = null; -293 try { -294 if (pomEntries.size() > 1) { -295 //extract POM to its own directory and add it as its own dependency -296 final Dependency newDependency = new Dependency(); -297 pom = extractPom(path, jar, newDependency); -298 -299 final String displayPath = String.format("%s%s%s", -300 dependency.getFilePath(), -301 File.separator, -302 path); -303 final String displayName = String.format("%s%s%s", -304 dependency.getFileName(), -305 File.separator, -306 path); -307 -308 newDependency.setFileName(displayName); -309 newDependency.setFilePath(displayPath); -310 pom.processProperties(pomProperties); -311 setPomEvidence(newDependency, pom, null); -312 engine.getDependencies().add(newDependency); -313 Collections.sort(engine.getDependencies()); -314 } else { -315 if (externalPom == null) { -316 pom = PomUtils.readPom(path, jar); -317 } else { -318 pom = PomUtils.readPom(externalPom); -319 } -320 pom.processProperties(pomProperties); -321 foundSomething |= setPomEvidence(dependency, pom, classes); -322 } -323 } catch (AnalysisException ex) { -324 LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath()); -325 LOGGER.trace("", ex); -326 } -327 } -328 return foundSomething; -329 } -330 -331 /** -332 * Given a path to a pom.xml within a JarFile, this method attempts to load a sibling pom.properties if one exists. -333 * -334 * @param path the path to the pom.xml within the JarFile -335 * @param jar the JarFile to load the pom.properties from -336 * @return a Properties object or null if no pom.properties was found -337 * @throws IOException thrown if there is an exception reading the pom.properties -338 */ -339 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { -340 Properties pomProperties = null; -341 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; -342 final ZipEntry propEntry = jar.getEntry(propPath); -343 if (propEntry != null) { -344 Reader reader = null; -345 try { -346 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); -347 pomProperties = new Properties(); -348 pomProperties.load(reader); -349 LOGGER.debug("Read pom.properties: {}", propPath); -350 } finally { -351 if (reader != null) { -352 try { -353 reader.close(); -354 } catch (IOException ex) { -355 LOGGER.trace("close error", ex); -356 } -357 } -358 } -359 } -360 return pomProperties; -361 } -362 -363 /** -364 * Searches a JarFile for pom.xml entries and returns a listing of these entries. -365 * -366 * @param jar the JarFile to search -367 * @return a list of pom.xml entries -368 * @throws IOException thrown if there is an exception reading a JarEntry -369 */ -370 private List<String> retrievePomListing(final JarFile jar) throws IOException { -371 final List<String> pomEntries = new ArrayList<String>(); -372 final Enumeration<JarEntry> entries = jar.entries(); -373 while (entries.hasMoreElements()) { -374 final JarEntry entry = entries.nextElement(); -375 final String entryName = (new File(entry.getName())).getName().toLowerCase(); -376 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { -377 LOGGER.trace("POM Entry found: {}", entry.getName()); -378 pomEntries.add(entry.getName()); -379 } -380 } -381 return pomEntries; -382 } -383 -384 /** -385 * Retrieves the specified POM from a jar file and converts it to a Model. -386 * -387 * @param path the path to the pom.xml file within the jar file -388 * @param jar the jar file to extract the pom from -389 * @param dependency the dependency being analyzed -390 * @return returns the POM object -391 * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM -392 * {@link org.owasp.dependencycheck.xml.pom.Model} object -393 */ -394 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { -395 InputStream input = null; -396 FileOutputStream fos = null; -397 final File tmpDir = getNextTempDirectory(); -398 final File file = new File(tmpDir, "pom.xml"); -399 try { -400 final ZipEntry entry = jar.getEntry(path); -401 input = jar.getInputStream(entry); -402 fos = new FileOutputStream(file); -403 IOUtils.copy(input, fos); -404 dependency.setActualFilePath(file.getAbsolutePath()); -405 } catch (IOException ex) { -406 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath()); -407 LOGGER.error("", ex); -408 } finally { -409 closeStream(fos); -410 closeStream(input); -411 } -412 return PomUtils.readPom(file); -413 } -414 -415 /** -416 * Silently closes an input stream ignoring errors. -417 * -418 * @param stream an input stream to close -419 */ -420 private void closeStream(InputStream stream) { -421 if (stream != null) { -422 try { -423 stream.close(); -424 } catch (IOException ex) { -425 LOGGER.trace("", ex); -426 } -427 } -428 } -429 -430 /** -431 * Silently closes an output stream ignoring errors. -432 * -433 * @param stream an output stream to close -434 */ -435 private void closeStream(OutputStream stream) { -436 if (stream != null) { -437 try { -438 stream.close(); -439 } catch (IOException ex) { -440 LOGGER.trace("", ex); -441 } -442 } -443 } -444 -445 /** -446 * Sets evidence from the pom on the supplied dependency. -447 * -448 * @param dependency the dependency to set data on -449 * @param pom the information from the pom -450 * @param classes a collection of ClassNameInformation - containing data about the fully qualified class names within the JAR -451 * file being analyzed -452 * @return true if there was evidence within the pom that we could use; otherwise false -453 */ -454 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { -455 boolean foundSomething = false; -456 boolean addAsIdentifier = true; -457 if (pom == null) { -458 return foundSomething; -459 } -460 String groupid = pom.getGroupId(); -461 String parentGroupId = pom.getParentGroupId(); -462 String artifactid = pom.getArtifactId(); -463 String parentArtifactId = pom.getParentArtifactId(); -464 String version = pom.getVersion(); -465 String parentVersion = pom.getParentVersion(); -466 -467 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { -468 parentGroupId = null; -469 parentArtifactId = null; -470 parentVersion = null; -471 } -472 -473 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { -474 groupid = parentGroupId; -475 } -476 -477 final String originalGroupID = groupid; -478 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { -479 groupid = groupid.substring(4); -480 } -481 -482 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { -483 artifactid = parentArtifactId; -484 } -485 -486 final String originalArtifactID = artifactid; -487 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { -488 artifactid = artifactid.substring(4); -489 } -490 -491 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { -492 version = parentVersion; -493 } -494 -495 if (groupid != null && !groupid.isEmpty()) { -496 foundSomething = true; -497 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); -498 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); -499 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); -500 addMatchingValues(classes, groupid, dependency.getProductEvidence()); -501 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { -502 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); -503 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); -504 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); -505 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); -506 } -507 } else { -508 addAsIdentifier = false; -509 } -510 -511 if (artifactid != null && !artifactid.isEmpty()) { -512 foundSomething = true; -513 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); -514 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); -515 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); -516 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); -517 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { -518 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); -519 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); -520 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); -521 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); -522 } -523 } else { -524 addAsIdentifier = false; -525 } -526 -527 if (version != null && !version.isEmpty()) { -528 foundSomething = true; -529 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); -530 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { -531 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); -532 } -533 } else { -534 addAsIdentifier = false; -535 } -536 -537 if (addAsIdentifier) { -538 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); -539 } -540 -541 // org name -542 final String org = pom.getOrganization(); -543 if (org != null && !org.isEmpty()) { -544 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); -545 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); -546 addMatchingValues(classes, org, dependency.getVendorEvidence()); -547 addMatchingValues(classes, org, dependency.getProductEvidence()); -548 } -549 //pom name -550 final String pomName = pom.getName(); -551 if (pomName -552 != null && !pomName.isEmpty()) { -553 foundSomething = true; -554 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -555 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -556 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); -557 addMatchingValues(classes, pomName, dependency.getProductEvidence()); -558 } -559 -560 //Description -561 final String description = pom.getDescription(); -562 if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { -563 foundSomething = true; -564 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); -565 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); -566 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); -567 } -568 -569 extractLicense(pom, dependency); -570 return foundSomething; -571 } -572 -573 /** -574 * Analyzes the path information of the classes contained within the JarAnalyzer to try and determine possible vendor or -575 * product names. If any are found they are stored in the packageVendor and packageProduct hashSets. -576 * -577 * @param classNames a list of class names -578 * @param dependency a dependency to analyze -579 * @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence. -580 */ -581 protected void analyzePackageNames(List<ClassNameInformation> classNames, -582 Dependency dependency, boolean addPackagesAsEvidence) { -583 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); -584 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); -585 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); -586 -587 final int classCount = classNames.size(); -588 final EvidenceCollection vendor = dependency.getVendorEvidence(); -589 final EvidenceCollection product = dependency.getProductEvidence(); -590 -591 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { -592 final float ratio = entry.getValue() / (float) classCount; -593 if (ratio > 0.5) { -594 //TODO remove weighting -595 vendor.addWeighting(entry.getKey()); -596 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -597 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -598 } -599 } -600 } -601 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { -602 final float ratio = entry.getValue() / (float) classCount; -603 if (ratio > 0.5) { -604 product.addWeighting(entry.getKey()); -605 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -606 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -607 } -608 } -609 } -610 } -611 -612 /** -613 * <p> -614 * Reads the manifest from the JAR file and collects the entries. Some vendorKey entries are:</p> -615 * <ul><li>Implementation Title</li> -616 * <li>Implementation Version</li> <li>Implementation Vendor</li> -617 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle Version</li> <li>Bundle Vendor</li> <li>Bundle -618 * Description</li> <li>Main Class</li> </ul> -619 * However, all but a handful of specific entries are read in. -620 * -621 * @param dependency A reference to the dependency -622 * @param classInformation a collection of class information -623 * @return whether evidence was identified parsing the manifest -624 * @throws IOException if there is an issue reading the JAR file -625 */ -626 protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException { -627 boolean foundSomething = false; -628 JarFile jar = null; -629 try { -630 jar = new JarFile(dependency.getActualFilePath()); -631 final Manifest manifest = jar.getManifest(); -632 if (manifest == null) { -633 //don't log this for javadoc or sources jar files -634 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") -635 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") -636 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") -637 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { -638 LOGGER.debug("Jar file '{}' does not contain a manifest.", -639 dependency.getFileName()); -640 } -641 return false; -642 } -643 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); -644 final EvidenceCollection productEvidence = dependency.getProductEvidence(); -645 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); -646 -647 String source = "Manifest"; -648 String specificationVersion = null; -649 boolean hasImplementationVersion = false; -650 -651 Attributes atts = manifest.getMainAttributes(); -652 for (Entry<Object, Object> entry : atts.entrySet()) { -653 String key = entry.getKey().toString(); -654 String value = atts.getValue(key); -655 if (HTML_DETECTION_PATTERN.matcher(value).find()) { -656 value = Jsoup.parse(value).text(); -657 } -658 if (IGNORE_VALUES.contains(value)) { -659 continue; -660 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { -661 foundSomething = true; -662 productEvidence.addEvidence(source, key, value, Confidence.HIGH); -663 addMatchingValues(classInformation, value, productEvidence); -664 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { -665 hasImplementationVersion = true; -666 foundSomething = true; -667 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -668 } else if ("specification-version".equalsIgnoreCase(key)) { -669 specificationVersion = key; -670 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { -671 foundSomething = true; -672 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -673 addMatchingValues(classInformation, value, vendorEvidence); -674 } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { -675 foundSomething = true; -676 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -677 addMatchingValues(classInformation, value, vendorEvidence); -678 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { -679 foundSomething = true; -680 addDescription(dependency, value, "manifest", key); -681 //productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -682 addMatchingValues(classInformation, value, productEvidence); -683 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { -684 foundSomething = true; -685 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -686 addMatchingValues(classInformation, value, productEvidence); -687 // //the following caused false positives. -688 // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { -689 // foundSomething = true; -690 // vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -691 // addMatchingValues(classInformation, value, vendorEvidence); -692 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { -693 foundSomething = true; -694 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -695 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { -696 continue; -697 //skipping main class as if this has important information to add -698 // it will be added during class name analysis... if other fields -699 // have the information from the class name then they will get added... -700 // foundSomething = true; -701 // productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -702 // vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -703 // addMatchingValues(classInformation, value, vendorEvidence); -704 // addMatchingValues(classInformation, value, productEvidence); -705 } else { -706 key = key.toLowerCase(); -707 if (!IGNORE_KEYS.contains(key) -708 && !key.endsWith("jdk") -709 && !key.contains("lastmodified") -710 && !key.endsWith("package") -711 && !key.endsWith("classpath") -712 && !key.endsWith("class-path") -713 && !key.endsWith("-scm") //todo change this to a regex? -714 && !key.startsWith("scm-") -715 && !value.trim().startsWith("scm:") -716 && !isImportPackage(key, value) -717 && !isPackage(key, value)) { -718 -719 foundSomething = true; -720 if (key.contains("version")) { -721 if (!key.contains("specification")) { -722 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -723 } -724 } else if ("build-id".equals(key)) { -725 int pos = value.indexOf('('); -726 if (pos >= 0) { -727 value = value.substring(0, pos - 1); -728 } -729 pos = value.indexOf('['); -730 if (pos >= 0) { -731 value = value.substring(0, pos - 1); -732 } -733 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -734 } else if (key.contains("title")) { -735 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -736 addMatchingValues(classInformation, value, productEvidence); -737 } else if (key.contains("vendor")) { -738 if (key.contains("specification")) { -739 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -740 } else { -741 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -742 addMatchingValues(classInformation, value, vendorEvidence); -743 } -744 } else if (key.contains("name")) { -745 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -746 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -747 addMatchingValues(classInformation, value, vendorEvidence); -748 addMatchingValues(classInformation, value, productEvidence); -749 } else if (key.contains("license")) { -750 addLicense(dependency, value); -751 } else { -752 if (key.contains("description")) { -753 addDescription(dependency, value, "manifest", key); +75 * The count of directories created during analysis. This is used for +76 * creating temporary directories. +77 */ +78 private static int dirCount = 0; +79 /** +80 * The system independent newline character. +81 */ +82 private static final String NEWLINE = System.getProperty("line.separator"); +83 /** +84 * A list of values in the manifest to ignore as they only result in false +85 * positives. +86 */ +87 private static final Set<String> IGNORE_VALUES = newHashSet( +88 "Sun Java System Application Server"); +89 /** +90 * A list of elements in the manifest to ignore. +91 */ +92 private static final Set<String> IGNORE_KEYS = newHashSet( +93 "built-by", +94 "created-by", +95 "builtby", +96 "createdby", +97 "build-jdk", +98 "buildjdk", +99 "ant-version", +100 "antversion", +101 "dynamicimportpackage", +102 "dynamicimport-package", +103 "dynamic-importpackage", +104 "dynamic-import-package", +105 "import-package", +106 "ignore-package", +107 "export-package", +108 "importpackage", +109 "ignorepackage", +110 "exportpackage", +111 "sealed", +112 "manifest-version", +113 "archiver-version", +114 "manifestversion", +115 "archiverversion", +116 "classpath", +117 "class-path", +118 "tool", +119 "bundle-manifestversion", +120 "bundlemanifestversion", +121 "bundle-vendor", +122 "include-resource", +123 "embed-dependency", +124 "ipojo-components", +125 "ipojo-extension", +126 "eclipse-sourcereferences"); +127 /** +128 * Deprecated Jar manifest attribute, that is, nonetheless, useful for +129 * analysis. +130 */ +131 @SuppressWarnings("deprecation") +132 private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID +133 .toString(); +134 /** +135 * item in some manifest, should be considered medium confidence. +136 */ +137 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 +138 /** +139 * item in some manifest, should be considered medium confidence. +140 */ +141 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 +142 /** +143 * item in some manifest, should be considered medium confidence. +144 */ +145 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core +146 /** +147 * A pattern to detect HTML within text. +148 */ +149 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); +150 +151 //</editor-fold> +152 /** +153 * Constructs a new JarAnalyzer. +154 */ +155 public JarAnalyzer() { +156 } +157 +158 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> +159 /** +160 * The name of the analyzer. +161 */ +162 private static final String ANALYZER_NAME = "Jar Analyzer"; +163 /** +164 * The phase that this analyzer is intended to run in. +165 */ +166 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +167 /** +168 * The set of file extensions supported by this analyzer. +169 */ +170 private static final String[] EXTENSIONS = {"jar", "war"}; +171 +172 /** +173 * The file filter used to determine which files this analyzer supports. +174 */ +175 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +176 +177 /** +178 * Returns the FileFilter. +179 * +180 * @return the FileFilter +181 */ +182 @Override +183 protected FileFilter getFileFilter() { +184 return FILTER; +185 } +186 +187 /** +188 * Returns the name of the analyzer. +189 * +190 * @return the name of the analyzer. +191 */ +192 @Override +193 public String getName() { +194 return ANALYZER_NAME; +195 } +196 +197 /** +198 * Returns the phase that the analyzer is intended to run in. +199 * +200 * @return the phase that the analyzer is intended to run in. +201 */ +202 @Override +203 public AnalysisPhase getAnalysisPhase() { +204 return ANALYSIS_PHASE; +205 } +206 //</editor-fold> +207 +208 /** +209 * Returns the key used in the properties file to reference the analyzer's +210 * enabled property. +211 * +212 * @return the analyzer's enabled property setting key +213 */ +214 @Override +215 protected String getAnalyzerEnabledSettingKey() { +216 return Settings.KEYS.ANALYZER_JAR_ENABLED; +217 } +218 +219 /** +220 * Loads a specified JAR file and collects information from the manifest and +221 * checksums to identify the correct CPE information. +222 * +223 * @param dependency the dependency to analyze. +224 * @param engine the engine that is scanning the dependencies +225 * @throws AnalysisException is thrown if there is an error reading the JAR +226 * file. +227 */ +228 @Override +229 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +230 try { +231 final List<ClassNameInformation> classNames = collectClassNames(dependency); +232 final String fileName = dependency.getFileName().toLowerCase(); +233 if (classNames.isEmpty() +234 && (fileName.endsWith("-sources.jar") +235 || fileName.endsWith("-javadoc.jar") +236 || fileName.endsWith("-src.jar") +237 || fileName.endsWith("-doc.jar"))) { +238 engine.getDependencies().remove(dependency); +239 } +240 final boolean hasManifest = parseManifest(dependency, classNames); +241 final boolean hasPOM = analyzePOM(dependency, classNames, engine); +242 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); +243 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); +244 } catch (IOException ex) { +245 throw new AnalysisException("Exception occurred reading the JAR file.", ex); +246 } +247 } +248 +249 /** +250 * Attempts to find a pom.xml within the JAR file. If found it extracts +251 * information and adds it to the evidence. This will attempt to interpolate +252 * the strings contained within the pom.properties if one exists. +253 * +254 * @param dependency the dependency being analyzed +255 * @param classes a collection of class name information +256 * @param engine the analysis engine, used to add additional dependencies +257 * @throws AnalysisException is thrown if there is an exception parsing the +258 * pom +259 * @return whether or not evidence was added to the dependency +260 */ +261 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { +262 boolean foundSomething = false; +263 final JarFile jar; +264 try { +265 jar = new JarFile(dependency.getActualFilePath()); +266 } catch (IOException ex) { +267 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath()); +268 LOGGER.trace("", ex); +269 return false; +270 } +271 List<String> pomEntries; +272 try { +273 pomEntries = retrievePomListing(jar); +274 } catch (IOException ex) { +275 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath()); +276 LOGGER.trace("", ex); +277 return false; +278 } +279 File externalPom = null; +280 if (pomEntries.isEmpty()) { +281 final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom"; +282 externalPom = new File(pomPath); +283 if (externalPom.isFile()) { +284 pomEntries.add(pomPath); +285 } else { +286 return false; +287 } +288 } +289 for (String path : pomEntries) { +290 LOGGER.debug("Reading pom entry: {}", path); +291 Properties pomProperties = null; +292 try { +293 if (externalPom == null) { +294 pomProperties = retrievePomProperties(path, jar); +295 } +296 } catch (IOException ex) { +297 LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex); +298 } +299 Model pom = null; +300 try { +301 if (pomEntries.size() > 1) { +302 //extract POM to its own directory and add it as its own dependency +303 final Dependency newDependency = new Dependency(); +304 pom = extractPom(path, jar, newDependency); +305 +306 final String displayPath = String.format("%s%s%s", +307 dependency.getFilePath(), +308 File.separator, +309 path); +310 final String displayName = String.format("%s%s%s", +311 dependency.getFileName(), +312 File.separator, +313 path); +314 +315 newDependency.setFileName(displayName); +316 newDependency.setFilePath(displayPath); +317 pom.processProperties(pomProperties); +318 setPomEvidence(newDependency, pom, null); +319 engine.getDependencies().add(newDependency); +320 Collections.sort(engine.getDependencies()); +321 } else { +322 if (externalPom == null) { +323 pom = PomUtils.readPom(path, jar); +324 } else { +325 pom = PomUtils.readPom(externalPom); +326 } +327 pom.processProperties(pomProperties); +328 foundSomething |= setPomEvidence(dependency, pom, classes); +329 } +330 } catch (AnalysisException ex) { +331 LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath()); +332 LOGGER.trace("", ex); +333 } +334 } +335 return foundSomething; +336 } +337 +338 /** +339 * Given a path to a pom.xml within a JarFile, this method attempts to load +340 * a sibling pom.properties if one exists. +341 * +342 * @param path the path to the pom.xml within the JarFile +343 * @param jar the JarFile to load the pom.properties from +344 * @return a Properties object or null if no pom.properties was found +345 * @throws IOException thrown if there is an exception reading the +346 * pom.properties +347 */ +348 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { +349 Properties pomProperties = null; +350 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; +351 final ZipEntry propEntry = jar.getEntry(propPath); +352 if (propEntry != null) { +353 Reader reader = null; +354 try { +355 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); +356 pomProperties = new Properties(); +357 pomProperties.load(reader); +358 LOGGER.debug("Read pom.properties: {}", propPath); +359 } finally { +360 if (reader != null) { +361 try { +362 reader.close(); +363 } catch (IOException ex) { +364 LOGGER.trace("close error", ex); +365 } +366 } +367 } +368 } +369 return pomProperties; +370 } +371 +372 /** +373 * Searches a JarFile for pom.xml entries and returns a listing of these +374 * entries. +375 * +376 * @param jar the JarFile to search +377 * @return a list of pom.xml entries +378 * @throws IOException thrown if there is an exception reading a JarEntry +379 */ +380 private List<String> retrievePomListing(final JarFile jar) throws IOException { +381 final List<String> pomEntries = new ArrayList<String>(); +382 final Enumeration<JarEntry> entries = jar.entries(); +383 while (entries.hasMoreElements()) { +384 final JarEntry entry = entries.nextElement(); +385 final String entryName = (new File(entry.getName())).getName().toLowerCase(); +386 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { +387 LOGGER.trace("POM Entry found: {}", entry.getName()); +388 pomEntries.add(entry.getName()); +389 } +390 } +391 return pomEntries; +392 } +393 +394 /** +395 * Retrieves the specified POM from a jar file and converts it to a Model. +396 * +397 * @param path the path to the pom.xml file within the jar file +398 * @param jar the jar file to extract the pom from +399 * @param dependency the dependency being analyzed +400 * @return returns the POM object +401 * @throws AnalysisException is thrown if there is an exception extracting +402 * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object +403 */ +404 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { +405 InputStream input = null; +406 FileOutputStream fos = null; +407 final File tmpDir = getNextTempDirectory(); +408 final File file = new File(tmpDir, "pom.xml"); +409 try { +410 final ZipEntry entry = jar.getEntry(path); +411 input = jar.getInputStream(entry); +412 fos = new FileOutputStream(file); +413 IOUtils.copy(input, fos); +414 dependency.setActualFilePath(file.getAbsolutePath()); +415 } catch (IOException ex) { +416 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath()); +417 LOGGER.error("", ex); +418 } finally { +419 closeStream(fos); +420 closeStream(input); +421 } +422 return PomUtils.readPom(file); +423 } +424 +425 /** +426 * Silently closes an input stream ignoring errors. +427 * +428 * @param stream an input stream to close +429 */ +430 private void closeStream(InputStream stream) { +431 if (stream != null) { +432 try { +433 stream.close(); +434 } catch (IOException ex) { +435 LOGGER.trace("", ex); +436 } +437 } +438 } +439 +440 /** +441 * Silently closes an output stream ignoring errors. +442 * +443 * @param stream an output stream to close +444 */ +445 private void closeStream(OutputStream stream) { +446 if (stream != null) { +447 try { +448 stream.close(); +449 } catch (IOException ex) { +450 LOGGER.trace("", ex); +451 } +452 } +453 } +454 +455 /** +456 * Sets evidence from the pom on the supplied dependency. +457 * +458 * @param dependency the dependency to set data on +459 * @param pom the information from the pom +460 * @param classes a collection of ClassNameInformation - containing data +461 * about the fully qualified class names within the JAR file being analyzed +462 * @return true if there was evidence within the pom that we could use; +463 * otherwise false +464 */ +465 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { +466 boolean foundSomething = false; +467 boolean addAsIdentifier = true; +468 if (pom == null) { +469 return foundSomething; +470 } +471 String groupid = pom.getGroupId(); +472 String parentGroupId = pom.getParentGroupId(); +473 String artifactid = pom.getArtifactId(); +474 String parentArtifactId = pom.getParentArtifactId(); +475 String version = pom.getVersion(); +476 String parentVersion = pom.getParentVersion(); +477 +478 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { +479 parentGroupId = null; +480 parentArtifactId = null; +481 parentVersion = null; +482 } +483 +484 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { +485 groupid = parentGroupId; +486 } +487 +488 final String originalGroupID = groupid; +489 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { +490 groupid = groupid.substring(4); +491 } +492 +493 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { +494 artifactid = parentArtifactId; +495 } +496 +497 final String originalArtifactID = artifactid; +498 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { +499 artifactid = artifactid.substring(4); +500 } +501 +502 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { +503 version = parentVersion; +504 } +505 +506 if (groupid != null && !groupid.isEmpty()) { +507 foundSomething = true; +508 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); +509 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); +510 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); +511 addMatchingValues(classes, groupid, dependency.getProductEvidence()); +512 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { +513 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); +514 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); +515 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); +516 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); +517 } +518 } else { +519 addAsIdentifier = false; +520 } +521 +522 if (artifactid != null && !artifactid.isEmpty()) { +523 foundSomething = true; +524 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); +525 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); +526 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); +527 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); +528 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { +529 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); +530 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); +531 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); +532 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); +533 } +534 } else { +535 addAsIdentifier = false; +536 } +537 +538 if (version != null && !version.isEmpty()) { +539 foundSomething = true; +540 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); +541 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { +542 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); +543 } +544 } else { +545 addAsIdentifier = false; +546 } +547 +548 if (addAsIdentifier) { +549 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); +550 } +551 +552 // org name +553 final String org = pom.getOrganization(); +554 if (org != null && !org.isEmpty()) { +555 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); +556 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); +557 addMatchingValues(classes, org, dependency.getVendorEvidence()); +558 addMatchingValues(classes, org, dependency.getProductEvidence()); +559 } +560 //pom name +561 final String pomName = pom.getName(); +562 if (pomName +563 != null && !pomName.isEmpty()) { +564 foundSomething = true; +565 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +566 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +567 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); +568 addMatchingValues(classes, pomName, dependency.getProductEvidence()); +569 } +570 +571 //Description +572 final String description = pom.getDescription(); +573 if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { +574 foundSomething = true; +575 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); +576 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); +577 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); +578 } +579 +580 final String projectURL = pom.getProjectURL(); +581 if (projectURL != null && !projectURL.trim().isEmpty()) { +582 dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST); +583 } +584 +585 extractLicense(pom, dependency); +586 return foundSomething; +587 } +588 +589 /** +590 * Analyzes the path information of the classes contained within the +591 * JarAnalyzer to try and determine possible vendor or product names. If any +592 * are found they are stored in the packageVendor and packageProduct +593 * hashSets. +594 * +595 * @param classNames a list of class names +596 * @param dependency a dependency to analyze +597 * @param addPackagesAsEvidence a flag indicating whether or not package +598 * names should be added as evidence. +599 */ +600 protected void analyzePackageNames(List<ClassNameInformation> classNames, +601 Dependency dependency, boolean addPackagesAsEvidence) { +602 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); +603 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); +604 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); +605 +606 final int classCount = classNames.size(); +607 final EvidenceCollection vendor = dependency.getVendorEvidence(); +608 final EvidenceCollection product = dependency.getProductEvidence(); +609 +610 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { +611 final float ratio = entry.getValue() / (float) classCount; +612 if (ratio > 0.5) { +613 //TODO remove weighting +614 vendor.addWeighting(entry.getKey()); +615 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +616 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +617 } +618 } +619 } +620 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { +621 final float ratio = entry.getValue() / (float) classCount; +622 if (ratio > 0.5) { +623 product.addWeighting(entry.getKey()); +624 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +625 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +626 } +627 } +628 } +629 } +630 +631 /** +632 * <p> +633 * Reads the manifest from the JAR file and collects the entries. Some +634 * vendorKey entries are:</p> +635 * <ul><li>Implementation Title</li> +636 * <li>Implementation Version</li> <li>Implementation Vendor</li> +637 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle +638 * Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main +639 * Class</li> </ul> +640 * However, all but a handful of specific entries are read in. +641 * +642 * @param dependency A reference to the dependency +643 * @param classInformation a collection of class information +644 * @return whether evidence was identified parsing the manifest +645 * @throws IOException if there is an issue reading the JAR file +646 */ +647 protected boolean parseManifest(Dependency dependency, +648 List<ClassNameInformation> classInformation) +649 throws IOException { +650 boolean foundSomething = false; +651 JarFile jar = null; +652 try { +653 jar = new JarFile(dependency.getActualFilePath()); +654 final Manifest manifest = jar.getManifest(); +655 if (manifest == null) { +656 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") +657 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") +658 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") +659 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { +660 LOGGER.debug("Jar file '{}' does not contain a manifest.", +661 dependency.getFileName()); +662 } +663 return false; +664 } +665 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); +666 final EvidenceCollection productEvidence = dependency.getProductEvidence(); +667 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); +668 +669 String source = "Manifest"; +670 String specificationVersion = null; +671 boolean hasImplementationVersion = false; +672 Attributes atts = manifest.getMainAttributes(); +673 for (Entry<Object, Object> entry : atts.entrySet()) { +674 String key = entry.getKey().toString(); +675 String value = atts.getValue(key); +676 if (HTML_DETECTION_PATTERN.matcher(value).find()) { +677 value = Jsoup.parse(value).text(); +678 } +679 if (IGNORE_VALUES.contains(value)) { +680 continue; +681 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { +682 foundSomething = true; +683 productEvidence.addEvidence(source, key, value, Confidence.HIGH); +684 addMatchingValues(classInformation, value, productEvidence); +685 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +686 hasImplementationVersion = true; +687 foundSomething = true; +688 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +689 } else if ("specification-version".equalsIgnoreCase(key)) { +690 specificationVersion = key; +691 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { +692 foundSomething = true; +693 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +694 addMatchingValues(classInformation, value, vendorEvidence); +695 } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { +696 foundSomething = true; +697 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +698 addMatchingValues(classInformation, value, vendorEvidence); +699 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { +700 foundSomething = true; +701 addDescription(dependency, value, "manifest", key); +702 addMatchingValues(classInformation, value, productEvidence); +703 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { +704 foundSomething = true; +705 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +706 addMatchingValues(classInformation, value, productEvidence); +707 // //the following caused false positives. +708 // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { +709 // foundSomething = true; +710 // vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +711 // addMatchingValues(classInformation, value, vendorEvidence); +712 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { +713 foundSomething = true; +714 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +715 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { +716 continue; +717 //skipping main class as if this has important information to add +718 // it will be added during class name analysis... if other fields +719 // have the information from the class name then they will get added... +720 } else { +721 key = key.toLowerCase(); +722 if (!IGNORE_KEYS.contains(key) +723 && !key.endsWith("jdk") +724 && !key.contains("lastmodified") +725 && !key.endsWith("package") +726 && !key.endsWith("classpath") +727 && !key.endsWith("class-path") +728 && !key.endsWith("-scm") //todo change this to a regex? +729 && !key.startsWith("scm-") +730 && !value.trim().startsWith("scm:") +731 && !isImportPackage(key, value) +732 && !isPackage(key, value)) { +733 foundSomething = true; +734 if (key.contains("version")) { +735 if (!key.contains("specification")) { +736 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +737 } +738 } else if ("build-id".equals(key)) { +739 int pos = value.indexOf('('); +740 if (pos >= 0) { +741 value = value.substring(0, pos - 1); +742 } +743 pos = value.indexOf('['); +744 if (pos >= 0) { +745 value = value.substring(0, pos - 1); +746 } +747 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +748 } else if (key.contains("title")) { +749 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +750 addMatchingValues(classInformation, value, productEvidence); +751 } else if (key.contains("vendor")) { +752 if (key.contains("specification")) { +753 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); 754 } else { -755 productEvidence.addEvidence(source, key, value, Confidence.LOW); -756 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -757 addMatchingValues(classInformation, value, vendorEvidence); -758 addMatchingValues(classInformation, value, productEvidence); -759 if (value.matches(".*\\d.*")) { -760 final StringTokenizer tokenizer = new StringTokenizer(value, " "); -761 while (tokenizer.hasMoreElements()) { -762 final String s = tokenizer.nextToken(); -763 if (s.matches("^[0-9.]+$")) { -764 versionEvidence.addEvidence(source, key, s, Confidence.LOW); -765 } -766 } -767 } -768 } -769 } -770 } -771 } -772 } -773 -774 final Map<String, Attributes> entries = manifest.getEntries(); -775 for (Iterator<String> it = entries.keySet().iterator(); it.hasNext();) { -776 final String name = it.next(); -777 source = "manifest: " + name; -778 atts = entries.get(name); -779 for (Entry<Object, Object> entry : atts.entrySet()) { -780 final String key = entry.getKey().toString(); -781 final String value = atts.getValue(key); -782 if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { -783 foundSomething = true; -784 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -785 addMatchingValues(classInformation, value, productEvidence); -786 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { -787 foundSomething = true; -788 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -789 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { -790 foundSomething = true; -791 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -792 addMatchingValues(classInformation, value, vendorEvidence); -793 } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) { +755 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +756 addMatchingValues(classInformation, value, vendorEvidence); +757 } +758 } else if (key.contains("name")) { +759 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +760 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +761 addMatchingValues(classInformation, value, vendorEvidence); +762 addMatchingValues(classInformation, value, productEvidence); +763 } else if (key.contains("license")) { +764 addLicense(dependency, value); +765 } else if (key.contains("description")) { +766 addDescription(dependency, value, "manifest", key); +767 } else { +768 productEvidence.addEvidence(source, key, value, Confidence.LOW); +769 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); +770 addMatchingValues(classInformation, value, vendorEvidence); +771 addMatchingValues(classInformation, value, productEvidence); +772 if (value.matches(".*\\d.*")) { +773 final StringTokenizer tokenizer = new StringTokenizer(value, " "); +774 while (tokenizer.hasMoreElements()) { +775 final String s = tokenizer.nextToken(); +776 if (s.matches("^[0-9.]+$")) { +777 versionEvidence.addEvidence(source, key, s, Confidence.LOW); +778 } +779 } +780 } +781 } +782 } +783 } +784 } +785 +786 for (Map.Entry<String, Attributes> item : manifest.getEntries().entrySet()) { +787 final String name = item.getKey(); +788 source = "manifest: " + name; +789 atts = item.getValue(); +790 for (Entry<Object, Object> entry : atts.entrySet()) { +791 final String key = entry.getKey().toString(); +792 final String value = atts.getValue(key); +793 if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { 794 foundSomething = true; 795 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); 796 addMatchingValues(classInformation, value, productEvidence); -797 } -798 } -799 } -800 if (specificationVersion != null && !hasImplementationVersion) { -801 foundSomething = true; -802 versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH); -803 } -804 } finally { -805 if (jar != null) { -806 jar.close(); -807 } -808 } -809 return foundSomething; -810 } -811 -812 /** -813 * Adds a description to the given dependency. If the description contains one of the following strings beyond 100 characters, -814 * then the description used will be trimmed to that position: -815 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses "</li></ul> -816 * -817 * @param dependency a dependency -818 * @param description the description -819 * @param source the source of the evidence -820 * @param key the "name" of the evidence -821 * @return if the description is trimmed, the trimmed version is returned; otherwise the original description is returned -822 */ -823 public static String addDescription(Dependency dependency, String description, String source, String key) { -824 if (dependency.getDescription() == null) { -825 dependency.setDescription(description); -826 } -827 String desc; -828 if (HTML_DETECTION_PATTERN.matcher(description).find()) { -829 desc = Jsoup.parse(description).text(); -830 } else { -831 desc = description; -832 } -833 dependency.setDescription(desc); -834 if (desc.length() > 100) { -835 desc = desc.replaceAll("\\s\\s+", " "); -836 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); -837 final int posLike = desc.toLowerCase().indexOf("like ", 100); -838 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); -839 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); -840 int pos = -1; -841 pos = Math.max(pos, posSuchAs); -842 if (pos >= 0 && posLike >= 0) { -843 pos = Math.min(pos, posLike); -844 } else { -845 pos = Math.max(pos, posLike); -846 } -847 if (pos >= 0 && posWillUse >= 0) { -848 pos = Math.min(pos, posWillUse); -849 } else { -850 pos = Math.max(pos, posWillUse); -851 } -852 if (pos >= 0 && posUses >= 0) { -853 pos = Math.min(pos, posUses); -854 } else { -855 pos = Math.max(pos, posUses); -856 } -857 -858 if (pos > 0) { -859 desc = desc.substring(0, pos) + "..."; +797 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +798 foundSomething = true; +799 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +800 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { +801 foundSomething = true; +802 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +803 addMatchingValues(classInformation, value, vendorEvidence); +804 } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) { +805 foundSomething = true; +806 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +807 addMatchingValues(classInformation, value, productEvidence); +808 } +809 } +810 } +811 if (specificationVersion != null && !hasImplementationVersion) { +812 foundSomething = true; +813 versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH); +814 } +815 } finally { +816 if (jar != null) { +817 jar.close(); +818 } +819 } +820 return foundSomething; +821 } +822 +823 /** +824 * Adds a description to the given dependency. If the description contains +825 * one of the following strings beyond 100 characters, then the description +826 * used will be trimmed to that position: +827 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses +828 * "</li></ul> +829 * +830 * @param dependency a dependency +831 * @param description the description +832 * @param source the source of the evidence +833 * @param key the "name" of the evidence +834 * @return if the description is trimmed, the trimmed version is returned; +835 * otherwise the original description is returned +836 */ +837 public static String addDescription(Dependency dependency, String description, String source, String key) { +838 if (dependency.getDescription() == null) { +839 dependency.setDescription(description); +840 } +841 String desc; +842 if (HTML_DETECTION_PATTERN.matcher(description).find()) { +843 desc = Jsoup.parse(description).text(); +844 } else { +845 desc = description; +846 } +847 dependency.setDescription(desc); +848 if (desc.length() > 100) { +849 desc = desc.replaceAll("\\s\\s+", " "); +850 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); +851 final int posLike = desc.toLowerCase().indexOf("like ", 100); +852 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); +853 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); +854 int pos = -1; +855 pos = Math.max(pos, posSuchAs); +856 if (pos >= 0 && posLike >= 0) { +857 pos = Math.min(pos, posLike); +858 } else { +859 pos = Math.max(pos, posLike); 860 } -861 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); -862 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); -863 } else { -864 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -865 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -866 } -867 return desc; -868 } -869 -870 /** -871 * Adds a license to the given dependency. -872 * -873 * @param d a dependency -874 * @param license the license -875 */ -876 private void addLicense(Dependency d, String license) { -877 if (d.getLicense() == null) { -878 d.setLicense(license); -879 } else if (!d.getLicense().contains(license)) { -880 d.setLicense(d.getLicense() + NEWLINE + license); -881 } +861 if (pos >= 0 && posWillUse >= 0) { +862 pos = Math.min(pos, posWillUse); +863 } else { +864 pos = Math.max(pos, posWillUse); +865 } +866 if (pos >= 0 && posUses >= 0) { +867 pos = Math.min(pos, posUses); +868 } else { +869 pos = Math.max(pos, posUses); +870 } +871 +872 if (pos > 0) { +873 desc = desc.substring(0, pos) + "..."; +874 } +875 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); +876 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); +877 } else { +878 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +879 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +880 } +881 return desc; 882 } 883 884 /** -885 * The parent directory for the individual directories per archive. -886 */ -887 private File tempFileLocation = null; -888 -889 /** -890 * Initializes the JarAnalyzer. -891 * -892 * @throws Exception is thrown if there is an exception creating a temporary directory -893 */ -894 @Override -895 public void initializeFileTypeAnalyzer() throws Exception { -896 final File baseDir = Settings.getTempDirectory(); -897 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -898 if (!tempFileLocation.delete()) { -899 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); -900 throw new AnalysisException(msg); -901 } -902 if (!tempFileLocation.mkdirs()) { -903 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); -904 throw new AnalysisException(msg); -905 } -906 } -907 -908 /** -909 * Deletes any files extracted from the JAR during analysis. -910 */ -911 @Override -912 public void close() { -913 if (tempFileLocation != null && tempFileLocation.exists()) { -914 LOGGER.debug("Attempting to delete temporary files"); -915 final boolean success = FileUtils.delete(tempFileLocation); -916 if (!success) { -917 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); -918 } -919 } -920 } -921 -922 /** -923 * Determines if the key value pair from the manifest is for an "import" type entry for package names. -924 * -925 * @param key the key from the manifest -926 * @param value the value from the manifest -927 * @return true or false depending on if it is believed the entry is an "import" entry -928 */ -929 private boolean isImportPackage(String key, String value) { -930 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); -931 final boolean matches = packageRx.matcher(value).matches(); -932 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); -933 } -934 -935 /** -936 * Cycles through an enumeration of JarEntries, contained within the dependency, and returns a list of the class names. This -937 * does not include core Java package names (i.e. java.* or javax.*). -938 * -939 * @param dependency the dependency being analyzed -940 * @return an list of fully qualified class names -941 */ -942 private List<ClassNameInformation> collectClassNames(Dependency dependency) { -943 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); -944 JarFile jar = null; -945 try { -946 jar = new JarFile(dependency.getActualFilePath()); -947 final Enumeration<JarEntry> entries = jar.entries(); -948 while (entries.hasMoreElements()) { -949 final JarEntry entry = entries.nextElement(); -950 final String name = entry.getName().toLowerCase(); -951 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. -952 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { -953 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); -954 classNames.add(className); -955 } -956 } -957 } catch (IOException ex) { -958 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName()); -959 LOGGER.debug("", ex); -960 } finally { -961 if (jar != null) { -962 try { -963 jar.close(); -964 } catch (IOException ex) { -965 LOGGER.trace("", ex); -966 } -967 } -968 } -969 return classNames; -970 } -971 -972 /** -973 * Cycles through the list of class names and places the package levels 0-3 into the provided maps for vendor and product. -974 * This is helpful when analyzing vendor/product as many times this is included in the package name. -975 * -976 * @param classNames a list of class names -977 * @param vendor HashMap of possible vendor names from package names (e.g. owasp) -978 * @param product HashMap of possible product names from package names (e.g. dependencycheck) -979 */ -980 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, -981 Map<String, Integer> vendor, Map<String, Integer> product) { -982 for (ClassNameInformation entry : classNames) { -983 final List<String> list = entry.getPackageStructure(); -984 addEntry(vendor, list.get(0)); -985 -986 if (list.size() == 2) { -987 addEntry(product, list.get(1)); -988 } -989 if (list.size() == 3) { -990 addEntry(vendor, list.get(1)); -991 addEntry(product, list.get(1)); -992 addEntry(product, list.get(2)); -993 } -994 if (list.size() >= 4) { -995 addEntry(vendor, list.get(1)); -996 addEntry(vendor, list.get(2)); -997 addEntry(product, list.get(1)); -998 addEntry(product, list.get(2)); -999 addEntry(product, list.get(3)); -1000 } -1001 } -1002 } -1003 -1004 /** -1005 * Adds an entry to the specified collection and sets the Integer (e.g. the count) to 1. If the entry already exists in the -1006 * collection then the Integer is incremented by 1. -1007 * -1008 * @param collection a collection of strings and their occurrence count -1009 * @param key the key to add to the collection -1010 */ -1011 private void addEntry(Map<String, Integer> collection, String key) { -1012 if (collection.containsKey(key)) { -1013 collection.put(key, collection.get(key) + 1); -1014 } else { -1015 collection.put(key, 1); -1016 } -1017 } -1018 -1019 /** -1020 * Cycles through the collection of class name information to see if parts of the package names are contained in the provided -1021 * value. If found, it will be added as the HIGHEST confidence evidence because we have more then one source corroborating the -1022 * value. -1023 * -1024 * @param classes a collection of class name information -1025 * @param value the value to check to see if it contains a package name -1026 * @param evidence the evidence collection to add new entries too -1027 */ -1028 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { -1029 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { -1030 return; -1031 } -1032 final String text = value.toLowerCase(); -1033 for (ClassNameInformation cni : classes) { -1034 for (String key : cni.getPackageStructure()) { -1035 final Pattern p = Pattern.compile("\b" + key + "\b"); -1036 if (p.matcher(text).find()) { -1037 //if (text.contains(key)) { //note, package structure elements are already lowercase. -1038 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); -1039 } -1040 } -1041 } -1042 } -1043 -1044 /** -1045 * Simple check to see if the attribute from a manifest is just a package name. -1046 * -1047 * @param key the key of the value to check -1048 * @param value the value to check -1049 * @return true if the value looks like a java package name, otherwise false -1050 */ -1051 private boolean isPackage(String key, String value) { -1052 -1053 return !key.matches(".*(version|title|vendor|name|license|description).*") -1054 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); -1055 -1056 } -1057 -1058 /** -1059 * Extracts the license information from the pom and adds it to the dependency. -1060 * -1061 * @param pom the pom object -1062 * @param dependency the dependency to add license information too -1063 */ -1064 public static void extractLicense(Model pom, Dependency dependency) { -1065 //license -1066 if (pom.getLicenses() != null) { -1067 String license = null; -1068 for (License lic : pom.getLicenses()) { -1069 String tmp = null; -1070 if (lic.getName() != null) { -1071 tmp = lic.getName(); -1072 } -1073 if (lic.getUrl() != null) { -1074 if (tmp == null) { -1075 tmp = lic.getUrl(); -1076 } else { -1077 tmp += ": " + lic.getUrl(); -1078 } -1079 } -1080 if (tmp == null) { -1081 continue; -1082 } -1083 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { -1084 tmp = Jsoup.parse(tmp).text(); -1085 } -1086 if (license == null) { -1087 license = tmp; -1088 } else { -1089 license += "\n" + tmp; -1090 } -1091 } -1092 if (license != null) { -1093 dependency.setLicense(license); -1094 -1095 } -1096 } -1097 } -1098 -1099 /** -1100 * Stores information about a class name. -1101 */ -1102 protected static class ClassNameInformation { -1103 -1104 /** -1105 * <p> -1106 * Stores information about a given class name. This class will keep the fully qualified class name and a list of the -1107 * important parts of the package structure. Up to the first four levels of the package structure are stored, excluding a -1108 * leading "org" or "com". Example:</p> -1109 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); -1110 * System.out.println(obj.getName()); -1111 * for (String p : obj.getPackageStructure()) -1112 * System.out.println(p); -1113 * </code> -1114 * <p> -1115 * Would result in:</p> -1116 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer -1117 * owasp -1118 * dependencycheck -1119 * analyzer -1120 * jaranalyzer</code> -1121 * -1122 * @param className a fully qualified class name -1123 */ -1124 ClassNameInformation(String className) { -1125 name = className; -1126 if (name.contains("/")) { -1127 final String[] tmp = className.toLowerCase().split("/"); -1128 int start = 0; -1129 int end = 3; -1130 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { -1131 start = 1; -1132 end = 4; -1133 } -1134 if (tmp.length <= end) { -1135 end = tmp.length - 1; -1136 } -1137 for (int i = start; i <= end; i++) { -1138 packageStructure.add(tmp[i]); -1139 } -1140 } else { -1141 packageStructure.add(name); -1142 } -1143 } -1144 /** -1145 * The fully qualified class name. -1146 */ -1147 private String name; -1148 -1149 /** -1150 * Get the value of name -1151 * -1152 * @return the value of name -1153 */ -1154 public String getName() { -1155 return name; -1156 } -1157 -1158 /** -1159 * Set the value of name -1160 * -1161 * @param name new value of name -1162 */ -1163 public void setName(String name) { -1164 this.name = name; -1165 } -1166 /** -1167 * Up to the first four levels of the package structure, excluding a leading "org" or "com". -1168 */ -1169 private final ArrayList<String> packageStructure = new ArrayList<String>(); -1170 -1171 /** -1172 * Get the value of packageStructure -1173 * -1174 * @return the value of packageStructure -1175 */ -1176 public ArrayList<String> getPackageStructure() { -1177 return packageStructure; -1178 } -1179 } -1180 -1181 /** -1182 * Retrieves the next temporary directory to extract an archive too. -1183 * -1184 * @return a directory -1185 * @throws AnalysisException thrown if unable to create temporary directory -1186 */ -1187 private File getNextTempDirectory() throws AnalysisException { -1188 dirCount += 1; -1189 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); -1190 //getting an exception for some directories not being able to be created; might be because the directory already exists? -1191 if (directory.exists()) { -1192 return getNextTempDirectory(); +885 * Adds a license to the given dependency. +886 * +887 * @param d a dependency +888 * @param license the license +889 */ +890 private void addLicense(Dependency d, String license) { +891 if (d.getLicense() == null) { +892 d.setLicense(license); +893 } else if (!d.getLicense().contains(license)) { +894 d.setLicense(d.getLicense() + NEWLINE + license); +895 } +896 } +897 +898 /** +899 * The parent directory for the individual directories per archive. +900 */ +901 private File tempFileLocation = null; +902 +903 /** +904 * Initializes the JarAnalyzer. +905 * +906 * @throws Exception is thrown if there is an exception creating a temporary +907 * directory +908 */ +909 @Override +910 public void initializeFileTypeAnalyzer() throws Exception { +911 final File baseDir = Settings.getTempDirectory(); +912 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +913 if (!tempFileLocation.delete()) { +914 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); +915 throw new AnalysisException(msg); +916 } +917 if (!tempFileLocation.mkdirs()) { +918 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); +919 throw new AnalysisException(msg); +920 } +921 } +922 +923 /** +924 * Deletes any files extracted from the JAR during analysis. +925 */ +926 @Override +927 public void close() { +928 if (tempFileLocation != null && tempFileLocation.exists()) { +929 LOGGER.debug("Attempting to delete temporary files"); +930 final boolean success = FileUtils.delete(tempFileLocation); +931 if (!success) { +932 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); +933 } +934 } +935 } +936 +937 /** +938 * Determines if the key value pair from the manifest is for an "import" +939 * type entry for package names. +940 * +941 * @param key the key from the manifest +942 * @param value the value from the manifest +943 * @return true or false depending on if it is believed the entry is an +944 * "import" entry +945 */ +946 private boolean isImportPackage(String key, String value) { +947 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); +948 final boolean matches = packageRx.matcher(value).matches(); +949 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); +950 } +951 +952 /** +953 * Cycles through an enumeration of JarEntries, contained within the +954 * dependency, and returns a list of the class names. This does not include +955 * core Java package names (i.e. java.* or javax.*). +956 * +957 * @param dependency the dependency being analyzed +958 * @return an list of fully qualified class names +959 */ +960 private List<ClassNameInformation> collectClassNames(Dependency dependency) { +961 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); +962 JarFile jar = null; +963 try { +964 jar = new JarFile(dependency.getActualFilePath()); +965 final Enumeration<JarEntry> entries = jar.entries(); +966 while (entries.hasMoreElements()) { +967 final JarEntry entry = entries.nextElement(); +968 final String name = entry.getName().toLowerCase(); +969 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. +970 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { +971 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); +972 classNames.add(className); +973 } +974 } +975 } catch (IOException ex) { +976 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName()); +977 LOGGER.debug("", ex); +978 } finally { +979 if (jar != null) { +980 try { +981 jar.close(); +982 } catch (IOException ex) { +983 LOGGER.trace("", ex); +984 } +985 } +986 } +987 return classNames; +988 } +989 +990 /** +991 * Cycles through the list of class names and places the package levels 0-3 +992 * into the provided maps for vendor and product. This is helpful when +993 * analyzing vendor/product as many times this is included in the package +994 * name. +995 * +996 * @param classNames a list of class names +997 * @param vendor HashMap of possible vendor names from package names (e.g. +998 * owasp) +999 * @param product HashMap of possible product names from package names (e.g. +1000 * dependencycheck) +1001 */ +1002 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, +1003 Map<String, Integer> vendor, Map<String, Integer> product) { +1004 for (ClassNameInformation entry : classNames) { +1005 final List<String> list = entry.getPackageStructure(); +1006 addEntry(vendor, list.get(0)); +1007 +1008 if (list.size() == 2) { +1009 addEntry(product, list.get(1)); +1010 } +1011 if (list.size() == 3) { +1012 addEntry(vendor, list.get(1)); +1013 addEntry(product, list.get(1)); +1014 addEntry(product, list.get(2)); +1015 } +1016 if (list.size() >= 4) { +1017 addEntry(vendor, list.get(1)); +1018 addEntry(vendor, list.get(2)); +1019 addEntry(product, list.get(1)); +1020 addEntry(product, list.get(2)); +1021 addEntry(product, list.get(3)); +1022 } +1023 } +1024 } +1025 +1026 /** +1027 * Adds an entry to the specified collection and sets the Integer (e.g. the +1028 * count) to 1. If the entry already exists in the collection then the +1029 * Integer is incremented by 1. +1030 * +1031 * @param collection a collection of strings and their occurrence count +1032 * @param key the key to add to the collection +1033 */ +1034 private void addEntry(Map<String, Integer> collection, String key) { +1035 if (collection.containsKey(key)) { +1036 collection.put(key, collection.get(key) + 1); +1037 } else { +1038 collection.put(key, 1); +1039 } +1040 } +1041 +1042 /** +1043 * Cycles through the collection of class name information to see if parts +1044 * of the package names are contained in the provided value. If found, it +1045 * will be added as the HIGHEST confidence evidence because we have more +1046 * then one source corroborating the value. +1047 * +1048 * @param classes a collection of class name information +1049 * @param value the value to check to see if it contains a package name +1050 * @param evidence the evidence collection to add new entries too +1051 */ +1052 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { +1053 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { +1054 return; +1055 } +1056 final String text = value.toLowerCase(); +1057 for (ClassNameInformation cni : classes) { +1058 for (String key : cni.getPackageStructure()) { +1059 final Pattern p = Pattern.compile("\b" + key + "\b"); +1060 if (p.matcher(text).find()) { +1061 //if (text.contains(key)) { //note, package structure elements are already lowercase. +1062 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); +1063 } +1064 } +1065 } +1066 } +1067 +1068 /** +1069 * Simple check to see if the attribute from a manifest is just a package +1070 * name. +1071 * +1072 * @param key the key of the value to check +1073 * @param value the value to check +1074 * @return true if the value looks like a java package name, otherwise false +1075 */ +1076 private boolean isPackage(String key, String value) { +1077 +1078 return !key.matches(".*(version|title|vendor|name|license|description).*") +1079 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); +1080 +1081 } +1082 +1083 /** +1084 * Extracts the license information from the pom and adds it to the +1085 * dependency. +1086 * +1087 * @param pom the pom object +1088 * @param dependency the dependency to add license information too +1089 */ +1090 public static void extractLicense(Model pom, Dependency dependency) { +1091 //license +1092 if (pom.getLicenses() != null) { +1093 String license = null; +1094 for (License lic : pom.getLicenses()) { +1095 String tmp = null; +1096 if (lic.getName() != null) { +1097 tmp = lic.getName(); +1098 } +1099 if (lic.getUrl() != null) { +1100 if (tmp == null) { +1101 tmp = lic.getUrl(); +1102 } else { +1103 tmp += ": " + lic.getUrl(); +1104 } +1105 } +1106 if (tmp == null) { +1107 continue; +1108 } +1109 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { +1110 tmp = Jsoup.parse(tmp).text(); +1111 } +1112 if (license == null) { +1113 license = tmp; +1114 } else { +1115 license += "\n" + tmp; +1116 } +1117 } +1118 if (license != null) { +1119 dependency.setLicense(license); +1120 +1121 } +1122 } +1123 } +1124 +1125 /** +1126 * Stores information about a class name. +1127 */ +1128 protected static class ClassNameInformation { +1129 +1130 /** +1131 * <p> +1132 * Stores information about a given class name. This class will keep the +1133 * fully qualified class name and a list of the important parts of the +1134 * package structure. Up to the first four levels of the package +1135 * structure are stored, excluding a leading "org" or "com". +1136 * Example:</p> +1137 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); +1138 * System.out.println(obj.getName()); +1139 * for (String p : obj.getPackageStructure()) +1140 * System.out.println(p); +1141 * </code> +1142 * <p> +1143 * Would result in:</p> +1144 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer +1145 * owasp +1146 * dependencycheck +1147 * analyzer +1148 * jaranalyzer</code> +1149 * +1150 * @param className a fully qualified class name +1151 */ +1152 ClassNameInformation(String className) { +1153 name = className; +1154 if (name.contains("/")) { +1155 final String[] tmp = className.toLowerCase().split("/"); +1156 int start = 0; +1157 int end = 3; +1158 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { +1159 start = 1; +1160 end = 4; +1161 } +1162 if (tmp.length <= end) { +1163 end = tmp.length - 1; +1164 } +1165 for (int i = start; i <= end; i++) { +1166 packageStructure.add(tmp[i]); +1167 } +1168 } else { +1169 packageStructure.add(name); +1170 } +1171 } +1172 /** +1173 * The fully qualified class name. +1174 */ +1175 private String name; +1176 +1177 /** +1178 * Get the value of name +1179 * +1180 * @return the value of name +1181 */ +1182 public String getName() { +1183 return name; +1184 } +1185 +1186 /** +1187 * Set the value of name +1188 * +1189 * @param name new value of name +1190 */ +1191 public void setName(String name) { +1192 this.name = name; 1193 } -1194 if (!directory.mkdirs()) { -1195 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); -1196 throw new AnalysisException(msg); -1197 } -1198 return directory; -1199 } -1200 } +1194 /** +1195 * Up to the first four levels of the package structure, excluding a +1196 * leading "org" or "com". +1197 */ +1198 private final ArrayList<String> packageStructure = new ArrayList<String>(); +1199 +1200 /** +1201 * Get the value of packageStructure +1202 * +1203 * @return the value of packageStructure +1204 */ +1205 public ArrayList<String> getPackageStructure() { +1206 return packageStructure; +1207 } +1208 } +1209 +1210 /** +1211 * Retrieves the next temporary directory to extract an archive too. +1212 * +1213 * @return a directory +1214 * @throws AnalysisException thrown if unable to create temporary directory +1215 */ +1216 private File getNextTempDirectory() throws AnalysisException { +1217 dirCount += 1; +1218 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); +1219 //getting an exception for some directories not being able to be created; might be because the directory already exists? +1220 if (directory.exists()) { +1221 return getNextTempDirectory(); +1222 } +1223 if (!directory.mkdirs()) { +1224 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); +1225 throw new AnalysisException(msg); +1226 } +1227 return directory; +1228 } +1229 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html index bdc2382a5..ebd893860 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html @@ -53,146 +53,147 @@ 45 * 46 * @author Dale Visser 47 */ -48 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { -49 -50 /** -51 * The logger. -52 */ -53 private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class); -54 -55 /** -56 * The name of the analyzer. -57 */ -58 private static final String ANALYZER_NAME = "Node.js Package Analyzer"; -59 -60 /** -61 * The phase that this analyzer is intended to run in. -62 */ -63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -64 -65 /** -66 * The file name to scan. -67 */ -68 public static final String PACKAGE_JSON = "package.json"; -69 /** -70 * Filter that detects files named "package.json". -71 */ -72 private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance() -73 .addFilenames(PACKAGE_JSON).build(); -74 -75 /** -76 * Returns the FileFilter -77 * -78 * @return the FileFilter -79 */ -80 @Override -81 protected FileFilter getFileFilter() { -82 return PACKAGE_JSON_FILTER; -83 } -84 -85 @Override -86 protected void initializeFileTypeAnalyzer() throws Exception { -87 // NO-OP -88 } -89 -90 /** -91 * Returns the name of the analyzer. -92 * -93 * @return the name of the analyzer. -94 */ -95 @Override -96 public String getName() { -97 return ANALYZER_NAME; -98 } -99 -100 /** -101 * Returns the phase that the analyzer is intended to run in. -102 * -103 * @return the phase that the analyzer is intended to run in. -104 */ -105 @Override -106 public AnalysisPhase getAnalysisPhase() { -107 return ANALYSIS_PHASE; -108 } -109 -110 /** -111 * Returns the key used in the properties file to reference the analyzer's enabled property. -112 * -113 * @return the analyzer's enabled property setting key -114 */ -115 @Override -116 protected String getAnalyzerEnabledSettingKey() { -117 return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED; -118 } -119 -120 @Override -121 protected void analyzeFileType(Dependency dependency, Engine engine) -122 throws AnalysisException { -123 final File file = dependency.getActualFile(); -124 JsonReader jsonReader; -125 try { -126 jsonReader = Json.createReader(FileUtils.openInputStream(file)); -127 } catch (IOException e) { -128 throw new AnalysisException( -129 "Problem occurred while reading dependency file.", e); -130 } -131 try { -132 final JsonObject json = jsonReader.readObject(); -133 final EvidenceCollection productEvidence = dependency.getProductEvidence(); -134 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); -135 if (json.containsKey("name")) { -136 final Object value = json.get("name"); -137 if (value instanceof JsonString) { -138 final String valueString = ((JsonString) value).getString(); -139 productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST); -140 vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW); -141 } else { -142 LOGGER.warn("JSON value not string as expected: {}", value); -143 } -144 } -145 addToEvidence(json, productEvidence, "description"); -146 addToEvidence(json, vendorEvidence, "author"); -147 addToEvidence(json, dependency.getVersionEvidence(), "version"); -148 dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName())); -149 } catch (JsonException e) { -150 LOGGER.warn("Failed to parse package.json file.", e); -151 } finally { -152 jsonReader.close(); -153 } -154 } -155 -156 /** -157 * Adds information to an evidence collection from the node json configuration. -158 * -159 * @param json information from node.js -160 * @param collection a set of evidence about a dependency -161 * @param key the key to obtain the data from the json information -162 */ -163 private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) { -164 if (json.containsKey(key)) { -165 final JsonValue value = json.get(key); -166 if (value instanceof JsonString) { -167 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST); -168 } else if (value instanceof JsonObject) { -169 final JsonObject jsonObject = (JsonObject) value; -170 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) { -171 final String property = entry.getKey(); -172 final JsonValue subValue = entry.getValue(); -173 if (subValue instanceof JsonString) { -174 collection.addEvidence(PACKAGE_JSON, -175 String.format("%s.%s", key, property), -176 ((JsonString) subValue).getString(), -177 Confidence.HIGHEST); -178 } else { -179 LOGGER.warn("JSON sub-value not string as expected: {}", subValue); -180 } -181 } -182 } else { -183 LOGGER.warn("JSON value not string or JSON object as expected: {}", value); -184 } -185 } -186 } -187 } +48 @Experimental +49 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { +50 +51 /** +52 * The logger. +53 */ +54 private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class); +55 +56 /** +57 * The name of the analyzer. +58 */ +59 private static final String ANALYZER_NAME = "Node.js Package Analyzer"; +60 +61 /** +62 * The phase that this analyzer is intended to run in. +63 */ +64 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +65 +66 /** +67 * The file name to scan. +68 */ +69 public static final String PACKAGE_JSON = "package.json"; +70 /** +71 * Filter that detects files named "package.json". +72 */ +73 private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance() +74 .addFilenames(PACKAGE_JSON).build(); +75 +76 /** +77 * Returns the FileFilter +78 * +79 * @return the FileFilter +80 */ +81 @Override +82 protected FileFilter getFileFilter() { +83 return PACKAGE_JSON_FILTER; +84 } +85 +86 @Override +87 protected void initializeFileTypeAnalyzer() throws Exception { +88 // NO-OP +89 } +90 +91 /** +92 * Returns the name of the analyzer. +93 * +94 * @return the name of the analyzer. +95 */ +96 @Override +97 public String getName() { +98 return ANALYZER_NAME; +99 } +100 +101 /** +102 * Returns the phase that the analyzer is intended to run in. +103 * +104 * @return the phase that the analyzer is intended to run in. +105 */ +106 @Override +107 public AnalysisPhase getAnalysisPhase() { +108 return ANALYSIS_PHASE; +109 } +110 +111 /** +112 * Returns the key used in the properties file to reference the analyzer's enabled property. +113 * +114 * @return the analyzer's enabled property setting key +115 */ +116 @Override +117 protected String getAnalyzerEnabledSettingKey() { +118 return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED; +119 } +120 +121 @Override +122 protected void analyzeFileType(Dependency dependency, Engine engine) +123 throws AnalysisException { +124 final File file = dependency.getActualFile(); +125 JsonReader jsonReader; +126 try { +127 jsonReader = Json.createReader(FileUtils.openInputStream(file)); +128 } catch (IOException e) { +129 throw new AnalysisException( +130 "Problem occurred while reading dependency file.", e); +131 } +132 try { +133 final JsonObject json = jsonReader.readObject(); +134 final EvidenceCollection productEvidence = dependency.getProductEvidence(); +135 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); +136 if (json.containsKey("name")) { +137 final Object value = json.get("name"); +138 if (value instanceof JsonString) { +139 final String valueString = ((JsonString) value).getString(); +140 productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST); +141 vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW); +142 } else { +143 LOGGER.warn("JSON value not string as expected: {}", value); +144 } +145 } +146 addToEvidence(json, productEvidence, "description"); +147 addToEvidence(json, vendorEvidence, "author"); +148 addToEvidence(json, dependency.getVersionEvidence(), "version"); +149 dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName())); +150 } catch (JsonException e) { +151 LOGGER.warn("Failed to parse package.json file.", e); +152 } finally { +153 jsonReader.close(); +154 } +155 } +156 +157 /** +158 * Adds information to an evidence collection from the node json configuration. +159 * +160 * @param json information from node.js +161 * @param collection a set of evidence about a dependency +162 * @param key the key to obtain the data from the json information +163 */ +164 private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) { +165 if (json.containsKey(key)) { +166 final JsonValue value = json.get(key); +167 if (value instanceof JsonString) { +168 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST); +169 } else if (value instanceof JsonObject) { +170 final JsonObject jsonObject = (JsonObject) value; +171 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) { +172 final String property = entry.getKey(); +173 final JsonValue subValue = entry.getValue(); +174 if (subValue instanceof JsonString) { +175 collection.addEvidence(PACKAGE_JSON, +176 String.format("%s.%s", key, property), +177 ((JsonString) subValue).getString(), +178 Confidence.HIGHEST); +179 } else { +180 LOGGER.warn("JSON sub-value not string as expected: {}", subValue); +181 } +182 } +183 } else { +184 LOGGER.warn("JSON value not string or JSON object as expected: {}", value); +185 } +186 } +187 } +188 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html index 180509d73..e59ace550 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html @@ -36,151 +36,189 @@ 28 import java.io.File; 29 import java.io.FileFilter; 30 import java.io.IOException; -31 import java.util.regex.Matcher; -32 import java.util.regex.Pattern; -33 -34 /** -35 * Used to analyze OpenSSL source code present in the file system. -36 * -37 * @author Dale Visser -38 */ -39 public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { -40 -41 private static final int HEXADECIMAL = 16; +31 import java.nio.charset.Charset; +32 import java.util.regex.Matcher; +33 import java.util.regex.Pattern; +34 +35 /** +36 * Used to analyze OpenSSL source code present in the file system. +37 * +38 * @author Dale Visser +39 */ +40 public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { +41 42 /** -43 * Filename to analyze. All other .h files get removed from consideration. +43 * Hexadecimal. 44 */ -45 private static final String OPENSSLV_H = "opensslv.h"; -46 -47 /** -48 * Filter that detects files named "__init__.py". -49 */ -50 private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build(); -51 private static final Pattern VERSION_PATTERN = Pattern.compile( -52 "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL -53 | Pattern.CASE_INSENSITIVE); -54 private static final int MAJOR_OFFSET = 28; -55 private static final long MINOR_MASK = 0x0ff00000L; -56 private static final int MINOR_OFFSET = 20; -57 private static final long FIX_MASK = 0x000ff000L; -58 private static final int FIX_OFFSET = 12; -59 private static final long PATCH_MASK = 0x00000ff0L; -60 private static final int PATCH_OFFSET = 4; -61 private static final int NUM_LETTERS = 26; -62 private static final int STATUS_MASK = 0x0000000f; -63 -64 /** -65 * Returns the open SSL version as a string. -66 * -67 * @param openSSLVersionConstant The open SSL version -68 * @return the version of openssl -69 */ -70 static String getOpenSSLVersion(long openSSLVersionConstant) { -71 final long major = openSSLVersionConstant >>> MAJOR_OFFSET; -72 final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET; -73 final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET; -74 final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET; -75 final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1)); -76 final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK); -77 final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode); -78 return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status); -79 } -80 +45 private static final int HEXADECIMAL = 16; +46 /** +47 * Filename to analyze. All other .h files get removed from consideration. +48 */ +49 private static final String OPENSSLV_H = "opensslv.h"; +50 +51 /** +52 * Filter that detects files named "__init__.py". +53 */ +54 private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build(); +55 /** +56 * Open SSL Version number pattern. +57 */ +58 private static final Pattern VERSION_PATTERN = Pattern.compile( +59 "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL +60 | Pattern.CASE_INSENSITIVE); +61 /** +62 * The offset of the major version number. +63 */ +64 private static final int MAJOR_OFFSET = 28; +65 /** +66 * The mask for the minor version number. +67 */ +68 private static final long MINOR_MASK = 0x0ff00000L; +69 /** +70 * The offset of the minor version number. +71 */ +72 private static final int MINOR_OFFSET = 20; +73 /** +74 * The max for the fix version. +75 */ +76 private static final long FIX_MASK = 0x000ff000L; +77 /** +78 * The offset for the fix version. +79 */ +80 private static final int FIX_OFFSET = 12; 81 /** -82 * Returns the name of the Python Package Analyzer. -83 * -84 * @return the name of the analyzer -85 */ -86 @Override -87 public String getName() { -88 return "OpenSSL Source Analyzer"; -89 } -90 -91 /** -92 * Tell that we are used for information collection. -93 * -94 * @return INFORMATION_COLLECTION +82 * The mask for the patch version. +83 */ +84 private static final long PATCH_MASK = 0x00000ff0L; +85 /** +86 * The offset for the patch version. +87 */ +88 private static final int PATCH_OFFSET = 4; +89 /** +90 * Number of letters. +91 */ +92 private static final int NUM_LETTERS = 26; +93 /** +94 * The status mask. 95 */ -96 @Override -97 public AnalysisPhase getAnalysisPhase() { -98 return AnalysisPhase.INFORMATION_COLLECTION; -99 } -100 -101 /** -102 * Returns the set of supported file extensions. -103 * -104 * @return the set of supported file extensions -105 */ -106 @Override -107 protected FileFilter getFileFilter() { -108 return OPENSSLV_FILTER; -109 } -110 -111 /** -112 * No-op initializer implementation. -113 * -114 * @throws Exception never thrown -115 */ -116 @Override -117 protected void initializeFileTypeAnalyzer() throws Exception { -118 // Nothing to do here. -119 } -120 -121 /** -122 * Analyzes python packages and adds evidence to the dependency. -123 * -124 * @param dependency the dependency being analyzed -125 * @param engine the engine being used to perform the scan -126 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency -127 */ -128 @Override -129 protected void analyzeFileType(Dependency dependency, Engine engine) -130 throws AnalysisException { -131 final File file = dependency.getActualFile(); -132 final String parentName = file.getParentFile().getName(); -133 boolean found = false; -134 final String contents = getFileContents(file); -135 if (!contents.isEmpty()) { -136 final Matcher matcher = VERSION_PATTERN.matcher(contents); -137 if (matcher.find()) { -138 dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant", -139 getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH); -140 found = true; -141 } -142 } -143 if (found) { -144 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H); -145 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST); -146 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST); -147 } else { -148 engine.getDependencies().remove(dependency); -149 } -150 } -151 -152 /** -153 * Retrieves the contents of a given file. -154 * -155 * @param actualFile the file to read -156 * @return the contents of the file -157 * @throws AnalysisException thrown if there is an IO Exception -158 */ -159 private String getFileContents(final File actualFile) -160 throws AnalysisException { -161 String contents; -162 try { -163 contents = FileUtils.readFileToString(actualFile).trim(); -164 } catch (IOException e) { -165 throw new AnalysisException( -166 "Problem occurred while reading dependency file.", e); -167 } -168 return contents; -169 } -170 -171 @Override -172 protected String getAnalyzerEnabledSettingKey() { -173 return Settings.KEYS.ANALYZER_OPENSSL_ENABLED; -174 } -175 } +96 private static final int STATUS_MASK = 0x0000000f; +97 +98 /** +99 * Returns the open SSL version as a string. +100 * +101 * @param openSSLVersionConstant The open SSL version +102 * @return the version of openssl +103 */ +104 static String getOpenSSLVersion(long openSSLVersionConstant) { +105 final long major = openSSLVersionConstant >>> MAJOR_OFFSET; +106 final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET; +107 final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET; +108 final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET; +109 final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1)); +110 final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK); +111 final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode); +112 return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status); +113 } +114 +115 /** +116 * Returns the name of the Python Package Analyzer. +117 * +118 * @return the name of the analyzer +119 */ +120 @Override +121 public String getName() { +122 return "OpenSSL Source Analyzer"; +123 } +124 +125 /** +126 * Tell that we are used for information collection. +127 * +128 * @return INFORMATION_COLLECTION +129 */ +130 @Override +131 public AnalysisPhase getAnalysisPhase() { +132 return AnalysisPhase.INFORMATION_COLLECTION; +133 } +134 +135 /** +136 * Returns the set of supported file extensions. +137 * +138 * @return the set of supported file extensions +139 */ +140 @Override +141 protected FileFilter getFileFilter() { +142 return OPENSSLV_FILTER; +143 } +144 +145 /** +146 * No-op initializer implementation. +147 * +148 * @throws Exception never thrown +149 */ +150 @Override +151 protected void initializeFileTypeAnalyzer() throws Exception { +152 // Nothing to do here. +153 } +154 +155 /** +156 * Analyzes python packages and adds evidence to the dependency. +157 * +158 * @param dependency the dependency being analyzed +159 * @param engine the engine being used to perform the scan +160 * @throws AnalysisException thrown if there is an unrecoverable error +161 * analyzing the dependency +162 */ +163 @Override +164 protected void analyzeFileType(Dependency dependency, Engine engine) +165 throws AnalysisException { +166 final File file = dependency.getActualFile(); +167 final String parentName = file.getParentFile().getName(); +168 boolean found = false; +169 final String contents = getFileContents(file); +170 if (!contents.isEmpty()) { +171 final Matcher matcher = VERSION_PATTERN.matcher(contents); +172 if (matcher.find()) { +173 dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant", +174 getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH); +175 found = true; +176 } +177 } +178 if (found) { +179 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H); +180 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST); +181 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST); +182 } else { +183 engine.getDependencies().remove(dependency); +184 } +185 } +186 +187 /** +188 * Retrieves the contents of a given file. +189 * +190 * @param actualFile the file to read +191 * @return the contents of the file +192 * @throws AnalysisException thrown if there is an IO Exception +193 */ +194 private String getFileContents(final File actualFile) +195 throws AnalysisException { +196 try { +197 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); +198 } catch (IOException e) { +199 throw new AnalysisException( +200 "Problem occurred while reading dependency file.", e); +201 } +202 } +203 +204 /** +205 * Returns the setting for the analyzer enabled setting key. +206 * +207 * @return the setting for the analyzer enabled setting key +208 */ +209 @Override +210 protected String getAnalyzerEnabledSettingKey() { +211 return Settings.KEYS.ANALYZER_OPENSSL_ENABLED; +212 } +213 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html index b7de77c88..0259a9aa0 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html @@ -58,328 +58,329 @@ 50 * 51 * @author Dale Visser 52 */ -53 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { -54 -55 /** -56 * Name of egg metadata files to analyze. -57 */ -58 private static final String PKG_INFO = "PKG-INFO"; -59 -60 /** -61 * Name of wheel metadata files to analyze. -62 */ -63 private static final String METADATA = "METADATA"; -64 -65 /** -66 * The logger. -67 */ -68 private static final Logger LOGGER = LoggerFactory -69 .getLogger(PythonDistributionAnalyzer.class); -70 -71 /** -72 * The count of directories created during analysis. This is used for creating temporary directories. -73 */ -74 private static int dirCount = 0; -75 -76 /** -77 * The name of the analyzer. -78 */ -79 private static final String ANALYZER_NAME = "Python Distribution Analyzer"; -80 /** -81 * The phase that this analyzer is intended to run in. -82 */ -83 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -84 -85 /** -86 * The set of file extensions supported by this analyzer. -87 */ -88 private static final String[] EXTENSIONS = {"whl", "egg", "zip"}; -89 -90 /** -91 * Used to match on egg archive candidate extensions. -92 */ -93 private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build(); -94 -95 /** -96 * Used to detect files with a .whl extension. -97 */ -98 private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build(); -99 -100 /** -101 * The parent directory for the individual directories per archive. -102 */ -103 private File tempFileLocation; -104 -105 /** -106 * Filter that detects *.dist-info files (but doesn't verify they are directories. -107 */ -108 private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( -109 ".dist-info"); -110 -111 /** -112 * Filter that detects files named "METADATA". -113 */ -114 private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( -115 "EGG-INFO"); -116 -117 /** -118 * Filter that detects files named "METADATA". -119 */ -120 private static final NameFileFilter METADATA_FILTER = new NameFileFilter( -121 METADATA); -122 -123 /** -124 * Filter that detects files named "PKG-INFO". -125 */ -126 private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter( -127 PKG_INFO); -128 -129 /** -130 * The file filter used to determine which files this analyzer supports. -131 */ -132 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters( -133 METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build(); -134 -135 /** -136 * Returns the FileFilter -137 * -138 * @return the FileFilter -139 */ -140 @Override -141 protected FileFilter getFileFilter() { -142 return FILTER; -143 } -144 -145 /** -146 * Returns the name of the analyzer. -147 * -148 * @return the name of the analyzer. -149 */ -150 @Override -151 public String getName() { -152 return ANALYZER_NAME; -153 } -154 -155 /** -156 * Returns the phase that the analyzer is intended to run in. -157 * -158 * @return the phase that the analyzer is intended to run in. -159 */ -160 @Override -161 public AnalysisPhase getAnalysisPhase() { -162 return ANALYSIS_PHASE; -163 } -164 -165 /** -166 * Returns the key used in the properties file to reference the analyzer's enabled property. -167 * -168 * @return the analyzer's enabled property setting key -169 */ -170 @Override -171 protected String getAnalyzerEnabledSettingKey() { -172 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; -173 } -174 -175 @Override -176 protected void analyzeFileType(Dependency dependency, Engine engine) -177 throws AnalysisException { -178 final File actualFile = dependency.getActualFile(); -179 if (WHL_FILTER.accept(actualFile)) { -180 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, -181 METADATA_FILTER); -182 } else if (EGG_OR_ZIP.accept(actualFile)) { -183 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, -184 PKG_INFO_FILTER); -185 } else { -186 final String name = actualFile.getName(); -187 final boolean metadata = METADATA.equals(name); -188 if (metadata || PKG_INFO.equals(name)) { -189 final File parent = actualFile.getParentFile(); -190 final String parentName = parent.getName(); -191 dependency.setDisplayFileName(parentName + "/" + name); -192 if (parent.isDirectory() -193 && (metadata && parentName.endsWith(".dist-info") -194 || parentName.endsWith(".egg-info") || "EGG-INFO" -195 .equals(parentName))) { -196 collectWheelMetadata(dependency, actualFile); -197 } -198 } -199 } -200 } -201 -202 /** -203 * Collects the meta data from an archive. -204 * -205 * @param dependency the archive being scanned -206 * @param folderFilter the filter to apply to the folder -207 * @param metadataFilter the filter to apply to the meta data -208 * @throws AnalysisException thrown when there is a problem analyzing the dependency -209 */ -210 private void collectMetadataFromArchiveFormat(Dependency dependency, -211 FilenameFilter folderFilter, FilenameFilter metadataFilter) -212 throws AnalysisException { -213 final File temp = getNextTempDirectory(); -214 LOGGER.debug("{} exists? {}", temp, temp.exists()); -215 try { -216 ExtractionUtil.extractFilesUsingFilter( -217 new File(dependency.getActualFilePath()), temp, -218 metadataFilter); -219 } catch (ExtractionException ex) { -220 throw new AnalysisException(ex); -221 } -222 -223 collectWheelMetadata( -224 dependency, -225 getMatchingFile(getMatchingFile(temp, folderFilter), -226 metadataFilter)); -227 } -228 -229 /** -230 * Makes sure a usable temporary directory is available. -231 * -232 * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created -233 */ -234 @Override -235 protected void initializeFileTypeAnalyzer() throws Exception { -236 final File baseDir = Settings.getTempDirectory(); -237 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -238 if (!tempFileLocation.delete()) { -239 final String msg = String.format( -240 "Unable to delete temporary file '%s'.", -241 tempFileLocation.getAbsolutePath()); -242 throw new AnalysisException(msg); -243 } -244 if (!tempFileLocation.mkdirs()) { -245 final String msg = String.format( -246 "Unable to create directory '%s'.", -247 tempFileLocation.getAbsolutePath()); -248 throw new AnalysisException(msg); -249 } -250 } -251 -252 /** -253 * Deletes any files extracted from the Wheel during analysis. -254 */ -255 @Override -256 public void close() { -257 if (tempFileLocation != null && tempFileLocation.exists()) { -258 LOGGER.debug("Attempting to delete temporary files"); -259 final boolean success = FileUtils.delete(tempFileLocation); -260 if (!success) { -261 LOGGER.warn( -262 "Failed to delete some temporary files, see the log for more details"); -263 } -264 } -265 } -266 -267 /** -268 * Gathers evidence from the METADATA file. -269 * -270 * @param dependency the dependency being analyzed -271 * @param file a reference to the manifest/properties file -272 */ -273 private static void collectWheelMetadata(Dependency dependency, File file) { -274 final InternetHeaders headers = getManifestProperties(file); -275 addPropertyToEvidence(headers, dependency.getVersionEvidence(), -276 "Version", Confidence.HIGHEST); -277 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", -278 Confidence.HIGHEST); -279 final String url = headers.getHeader("Home-page", null); -280 final EvidenceCollection vendorEvidence = dependency -281 .getVendorEvidence(); -282 if (StringUtils.isNotBlank(url)) { -283 if (UrlStringUtils.isUrl(url)) { -284 vendorEvidence.addEvidence(METADATA, "vendor", url, -285 Confidence.MEDIUM); -286 } -287 } -288 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); -289 final String summary = headers.getHeader("Summary", null); -290 if (StringUtils.isNotBlank(summary)) { -291 JarAnalyzer -292 .addDescription(dependency, summary, METADATA, "summary"); -293 } -294 } -295 -296 /** -297 * Adds a value to the evidence collection. -298 * -299 * @param headers the properties collection -300 * @param evidence the evidence collection to add the value -301 * @param property the property name -302 * @param confidence the confidence of the evidence -303 */ -304 private static void addPropertyToEvidence(InternetHeaders headers, -305 EvidenceCollection evidence, String property, Confidence confidence) { -306 final String value = headers.getHeader(property, null); -307 LOGGER.debug("Property: {}, Value: {}", property, value); -308 if (StringUtils.isNotBlank(value)) { -309 evidence.addEvidence(METADATA, property, value, confidence); -310 } -311 } -312 -313 /** -314 * Returns a list of files that match the given filter, this does not recursively scan the directory. -315 * -316 * @param folder the folder to filter -317 * @param filter the filter to apply to the files in the directory -318 * @return the list of Files in the directory that match the provided filter -319 */ -320 private static File getMatchingFile(File folder, FilenameFilter filter) { -321 File result = null; -322 final File[] matches = folder.listFiles(filter); -323 if (null != matches && 1 == matches.length) { -324 result = matches[0]; -325 } -326 return result; -327 } -328 -329 /** -330 * Reads the manifest entries from the provided file. -331 * -332 * @param manifest the manifest -333 * @return the manifest entries -334 */ -335 private static InternetHeaders getManifestProperties(File manifest) { -336 final InternetHeaders result = new InternetHeaders(); -337 if (null == manifest) { -338 LOGGER.debug("Manifest file not found."); -339 } else { -340 try { -341 result.load(new AutoCloseInputStream(new BufferedInputStream( -342 new FileInputStream(manifest)))); -343 } catch (MessagingException e) { -344 LOGGER.warn(e.getMessage(), e); -345 } catch (FileNotFoundException e) { -346 LOGGER.warn(e.getMessage(), e); -347 } -348 } -349 return result; -350 } -351 -352 /** -353 * Retrieves the next temporary destination directory for extracting an archive. -354 * -355 * @return a directory -356 * @throws AnalysisException thrown if unable to create temporary directory -357 */ -358 private File getNextTempDirectory() throws AnalysisException { -359 File directory; -360 -361 // getting an exception for some directories not being able to be -362 // created; might be because the directory already exists? -363 do { -364 dirCount += 1; -365 directory = new File(tempFileLocation, String.valueOf(dirCount)); -366 } while (directory.exists()); -367 if (!directory.mkdirs()) { -368 throw new AnalysisException(String.format( -369 "Unable to create temp directory '%s'.", -370 directory.getAbsolutePath())); -371 } -372 return directory; -373 } -374 } +53 @Experimental +54 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { +55 +56 /** +57 * Name of egg metadata files to analyze. +58 */ +59 private static final String PKG_INFO = "PKG-INFO"; +60 +61 /** +62 * Name of wheel metadata files to analyze. +63 */ +64 private static final String METADATA = "METADATA"; +65 +66 /** +67 * The logger. +68 */ +69 private static final Logger LOGGER = LoggerFactory +70 .getLogger(PythonDistributionAnalyzer.class); +71 +72 /** +73 * The count of directories created during analysis. This is used for creating temporary directories. +74 */ +75 private static int dirCount = 0; +76 +77 /** +78 * The name of the analyzer. +79 */ +80 private static final String ANALYZER_NAME = "Python Distribution Analyzer"; +81 /** +82 * The phase that this analyzer is intended to run in. +83 */ +84 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +85 +86 /** +87 * The set of file extensions supported by this analyzer. +88 */ +89 private static final String[] EXTENSIONS = {"whl", "egg", "zip"}; +90 +91 /** +92 * Used to match on egg archive candidate extensions. +93 */ +94 private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build(); +95 +96 /** +97 * Used to detect files with a .whl extension. +98 */ +99 private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build(); +100 +101 /** +102 * The parent directory for the individual directories per archive. +103 */ +104 private File tempFileLocation; +105 +106 /** +107 * Filter that detects *.dist-info files (but doesn't verify they are directories. +108 */ +109 private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( +110 ".dist-info"); +111 +112 /** +113 * Filter that detects files named "METADATA". +114 */ +115 private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( +116 "EGG-INFO"); +117 +118 /** +119 * Filter that detects files named "METADATA". +120 */ +121 private static final NameFileFilter METADATA_FILTER = new NameFileFilter( +122 METADATA); +123 +124 /** +125 * Filter that detects files named "PKG-INFO". +126 */ +127 private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter( +128 PKG_INFO); +129 +130 /** +131 * The file filter used to determine which files this analyzer supports. +132 */ +133 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters( +134 METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build(); +135 +136 /** +137 * Returns the FileFilter +138 * +139 * @return the FileFilter +140 */ +141 @Override +142 protected FileFilter getFileFilter() { +143 return FILTER; +144 } +145 +146 /** +147 * Returns the name of the analyzer. +148 * +149 * @return the name of the analyzer. +150 */ +151 @Override +152 public String getName() { +153 return ANALYZER_NAME; +154 } +155 +156 /** +157 * Returns the phase that the analyzer is intended to run in. +158 * +159 * @return the phase that the analyzer is intended to run in. +160 */ +161 @Override +162 public AnalysisPhase getAnalysisPhase() { +163 return ANALYSIS_PHASE; +164 } +165 +166 /** +167 * Returns the key used in the properties file to reference the analyzer's enabled property. +168 * +169 * @return the analyzer's enabled property setting key +170 */ +171 @Override +172 protected String getAnalyzerEnabledSettingKey() { +173 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; +174 } +175 +176 @Override +177 protected void analyzeFileType(Dependency dependency, Engine engine) +178 throws AnalysisException { +179 final File actualFile = dependency.getActualFile(); +180 if (WHL_FILTER.accept(actualFile)) { +181 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, +182 METADATA_FILTER); +183 } else if (EGG_OR_ZIP.accept(actualFile)) { +184 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, +185 PKG_INFO_FILTER); +186 } else { +187 final String name = actualFile.getName(); +188 final boolean metadata = METADATA.equals(name); +189 if (metadata || PKG_INFO.equals(name)) { +190 final File parent = actualFile.getParentFile(); +191 final String parentName = parent.getName(); +192 dependency.setDisplayFileName(parentName + "/" + name); +193 if (parent.isDirectory() +194 && (metadata && parentName.endsWith(".dist-info") +195 || parentName.endsWith(".egg-info") || "EGG-INFO" +196 .equals(parentName))) { +197 collectWheelMetadata(dependency, actualFile); +198 } +199 } +200 } +201 } +202 +203 /** +204 * Collects the meta data from an archive. +205 * +206 * @param dependency the archive being scanned +207 * @param folderFilter the filter to apply to the folder +208 * @param metadataFilter the filter to apply to the meta data +209 * @throws AnalysisException thrown when there is a problem analyzing the dependency +210 */ +211 private void collectMetadataFromArchiveFormat(Dependency dependency, +212 FilenameFilter folderFilter, FilenameFilter metadataFilter) +213 throws AnalysisException { +214 final File temp = getNextTempDirectory(); +215 LOGGER.debug("{} exists? {}", temp, temp.exists()); +216 try { +217 ExtractionUtil.extractFilesUsingFilter( +218 new File(dependency.getActualFilePath()), temp, +219 metadataFilter); +220 } catch (ExtractionException ex) { +221 throw new AnalysisException(ex); +222 } +223 +224 collectWheelMetadata( +225 dependency, +226 getMatchingFile(getMatchingFile(temp, folderFilter), +227 metadataFilter)); +228 } +229 +230 /** +231 * Makes sure a usable temporary directory is available. +232 * +233 * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created +234 */ +235 @Override +236 protected void initializeFileTypeAnalyzer() throws Exception { +237 final File baseDir = Settings.getTempDirectory(); +238 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +239 if (!tempFileLocation.delete()) { +240 final String msg = String.format( +241 "Unable to delete temporary file '%s'.", +242 tempFileLocation.getAbsolutePath()); +243 throw new AnalysisException(msg); +244 } +245 if (!tempFileLocation.mkdirs()) { +246 final String msg = String.format( +247 "Unable to create directory '%s'.", +248 tempFileLocation.getAbsolutePath()); +249 throw new AnalysisException(msg); +250 } +251 } +252 +253 /** +254 * Deletes any files extracted from the Wheel during analysis. +255 */ +256 @Override +257 public void close() { +258 if (tempFileLocation != null && tempFileLocation.exists()) { +259 LOGGER.debug("Attempting to delete temporary files"); +260 final boolean success = FileUtils.delete(tempFileLocation); +261 if (!success) { +262 LOGGER.warn( +263 "Failed to delete some temporary files, see the log for more details"); +264 } +265 } +266 } +267 +268 /** +269 * Gathers evidence from the METADATA file. +270 * +271 * @param dependency the dependency being analyzed +272 * @param file a reference to the manifest/properties file +273 */ +274 private static void collectWheelMetadata(Dependency dependency, File file) { +275 final InternetHeaders headers = getManifestProperties(file); +276 addPropertyToEvidence(headers, dependency.getVersionEvidence(), +277 "Version", Confidence.HIGHEST); +278 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", +279 Confidence.HIGHEST); +280 final String url = headers.getHeader("Home-page", null); +281 final EvidenceCollection vendorEvidence = dependency +282 .getVendorEvidence(); +283 if (StringUtils.isNotBlank(url)) { +284 if (UrlStringUtils.isUrl(url)) { +285 vendorEvidence.addEvidence(METADATA, "vendor", url, +286 Confidence.MEDIUM); +287 } +288 } +289 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); +290 final String summary = headers.getHeader("Summary", null); +291 if (StringUtils.isNotBlank(summary)) { +292 JarAnalyzer +293 .addDescription(dependency, summary, METADATA, "summary"); +294 } +295 } +296 +297 /** +298 * Adds a value to the evidence collection. +299 * +300 * @param headers the properties collection +301 * @param evidence the evidence collection to add the value +302 * @param property the property name +303 * @param confidence the confidence of the evidence +304 */ +305 private static void addPropertyToEvidence(InternetHeaders headers, +306 EvidenceCollection evidence, String property, Confidence confidence) { +307 final String value = headers.getHeader(property, null); +308 LOGGER.debug("Property: {}, Value: {}", property, value); +309 if (StringUtils.isNotBlank(value)) { +310 evidence.addEvidence(METADATA, property, value, confidence); +311 } +312 } +313 +314 /** +315 * Returns a list of files that match the given filter, this does not recursively scan the directory. +316 * +317 * @param folder the folder to filter +318 * @param filter the filter to apply to the files in the directory +319 * @return the list of Files in the directory that match the provided filter +320 */ +321 private static File getMatchingFile(File folder, FilenameFilter filter) { +322 File result = null; +323 final File[] matches = folder.listFiles(filter); +324 if (null != matches && 1 == matches.length) { +325 result = matches[0]; +326 } +327 return result; +328 } +329 +330 /** +331 * Reads the manifest entries from the provided file. +332 * +333 * @param manifest the manifest +334 * @return the manifest entries +335 */ +336 private static InternetHeaders getManifestProperties(File manifest) { +337 final InternetHeaders result = new InternetHeaders(); +338 if (null == manifest) { +339 LOGGER.debug("Manifest file not found."); +340 } else { +341 try { +342 result.load(new AutoCloseInputStream(new BufferedInputStream( +343 new FileInputStream(manifest)))); +344 } catch (MessagingException e) { +345 LOGGER.warn(e.getMessage(), e); +346 } catch (FileNotFoundException e) { +347 LOGGER.warn(e.getMessage(), e); +348 } +349 } +350 return result; +351 } +352 +353 /** +354 * Retrieves the next temporary destination directory for extracting an archive. +355 * +356 * @return a directory +357 * @throws AnalysisException thrown if unable to create temporary directory +358 */ +359 private File getNextTempDirectory() throws AnalysisException { +360 File directory; +361 +362 // getting an exception for some directories not being able to be +363 // created; might be because the directory already exists? +364 do { +365 dirCount += 1; +366 directory = new File(tempFileLocation, String.valueOf(dirCount)); +367 } while (directory.exists()); +368 if (!directory.mkdirs()) { +369 throw new AnalysisException(String.format( +370 "Unable to create temp directory '%s'.", +371 directory.getAbsolutePath())); +372 } +373 return directory; +374 } +375 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html index 8bae17722..e87b494a2 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html @@ -40,288 +40,295 @@ 32 import java.io.File; 33 import java.io.FileFilter; 34 import java.io.IOException; -35 import java.util.ArrayList; -36 import java.util.List; -37 import java.util.regex.Matcher; -38 import java.util.regex.Pattern; -39 -40 /** -41 * Used to analyze a Python package, and collect information that can be used to determine the associated CPE. -42 * -43 * @author Dale Visser -44 */ -45 public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { -46 -47 /** -48 * Used when compiling file scanning regex patterns. -49 */ -50 private static final int REGEX_OPTIONS = Pattern.DOTALL -51 | Pattern.CASE_INSENSITIVE; -52 -53 /** -54 * Filename extensions for files to be analyzed. -55 */ -56 private static final String EXTENSIONS = "py"; -57 -58 /** -59 * Pattern for matching the module docstring in a source file. -60 */ -61 private static final Pattern MODULE_DOCSTRING = Pattern.compile( -62 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); -63 -64 /** -65 * Matches assignments to version variables in Python source code. -66 */ -67 private static final Pattern VERSION_PATTERN = Pattern.compile( -68 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", -69 REGEX_OPTIONS); -70 -71 /** -72 * Matches assignments to title variables in Python source code. -73 */ -74 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); -75 -76 /** -77 * Matches assignments to summary variables in Python source code. -78 */ -79 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); -80 -81 /** -82 * Matches assignments to URL/URL variables in Python source code. -83 */ -84 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); -85 -86 /** -87 * Matches assignments to home page variables in Python source code. -88 */ -89 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); -90 -91 /** -92 * Matches assignments to author variables in Python source code. -93 */ -94 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); -95 -96 /** -97 * Filter that detects files named "__init__.py". -98 */ -99 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); -100 -101 /** -102 * The file filter for python files. -103 */ -104 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); -105 -106 /** -107 * Returns the name of the Python Package Analyzer. -108 * -109 * @return the name of the analyzer -110 */ -111 @Override -112 public String getName() { -113 return "Python Package Analyzer"; -114 } -115 -116 /** -117 * Tell that we are used for information collection. -118 * -119 * @return INFORMATION_COLLECTION -120 */ -121 @Override -122 public AnalysisPhase getAnalysisPhase() { -123 return AnalysisPhase.INFORMATION_COLLECTION; -124 } -125 -126 /** -127 * The file filter used to determine which files this analyzer supports. -128 */ -129 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); -130 -131 /** -132 * Returns the FileFilter -133 * -134 * @return the FileFilter -135 */ -136 @Override -137 protected FileFilter getFileFilter() { -138 return FILTER; -139 } -140 -141 /** -142 * No-op initializer implementation. -143 * -144 * @throws Exception never thrown -145 */ -146 @Override -147 protected void initializeFileTypeAnalyzer() throws Exception { -148 // Nothing to do here. -149 } -150 -151 /** -152 * Utility function to create a regex pattern matcher. -153 * -154 * @param name the value to use when constructing the assignment pattern -155 * @return the compiled Pattern -156 */ -157 private static Pattern compileAssignPattern(String name) { -158 return Pattern.compile( -159 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), -160 REGEX_OPTIONS); -161 } -162 -163 /** -164 * Analyzes python packages and adds evidence to the dependency. -165 * -166 * @param dependency the dependency being analyzed -167 * @param engine the engine being used to perform the scan -168 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency -169 */ -170 @Override -171 protected void analyzeFileType(Dependency dependency, Engine engine) -172 throws AnalysisException { -173 final File file = dependency.getActualFile(); -174 final File parent = file.getParentFile(); -175 final String parentName = parent.getName(); -176 boolean found = false; -177 if (INIT_PY_FILTER.accept(file)) { -178 final File[] fileList = parent.listFiles(PY_FILTER); -179 if (fileList != null) { -180 for (final File sourceFile : fileList) { -181 found |= analyzeFileContents(dependency, sourceFile); -182 } -183 } -184 } -185 if (found) { -186 dependency.setDisplayFileName(parentName + "/__init__.py"); -187 dependency.getProductEvidence().addEvidence(file.getName(), -188 "PackageName", parentName, Confidence.HIGH); -189 } else { -190 // copy, alter and set in case some other thread is iterating over -191 final List<Dependency> dependencies = new ArrayList<Dependency>( -192 engine.getDependencies()); -193 dependencies.remove(dependency); -194 engine.setDependencies(dependencies); -195 } -196 } -197 -198 /** -199 * This should gather information from leading docstrings, file comments, and assignments to __version__, __title__, -200 * __summary__, __uri__, __url__, __home*page__, __author__, and their all caps equivalents. -201 * -202 * @param dependency the dependency being analyzed -203 * @param file the file name to analyze -204 * @return whether evidence was found -205 * @throws AnalysisException thrown if there is an unrecoverable error -206 */ -207 private boolean analyzeFileContents(Dependency dependency, File file) -208 throws AnalysisException { -209 String contents; -210 try { -211 contents = FileUtils.readFileToString(file).trim(); -212 } catch (IOException e) { -213 throw new AnalysisException( -214 "Problem occurred while reading dependency file.", e); -215 } -216 boolean found = false; -217 if (!contents.isEmpty()) { -218 final String source = file.getName(); -219 found = gatherEvidence(VERSION_PATTERN, contents, source, -220 dependency.getVersionEvidence(), "SourceVersion", -221 Confidence.MEDIUM); -222 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents, -223 source, "summary"); -224 if (INIT_PY_FILTER.accept(file)) { -225 found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2, -226 contents, source, "docstring"); -227 } -228 found |= gatherEvidence(TITLE_PATTERN, contents, source, -229 dependency.getProductEvidence(), "SourceTitle", -230 Confidence.LOW); -231 final EvidenceCollection vendorEvidence = dependency -232 .getVendorEvidence(); -233 found |= gatherEvidence(AUTHOR_PATTERN, contents, source, -234 vendorEvidence, "SourceAuthor", Confidence.MEDIUM); -235 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, -236 source, "URL", contents); -237 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, -238 vendorEvidence, source, "HomePage", contents); -239 } -240 return found; -241 } -242 -243 /** -244 * Adds summary information to the dependency -245 * -246 * @param dependency the dependency being analyzed -247 * @param pattern the pattern used to perform analysis -248 * @param group the group from the pattern that indicates the data to use -249 * @param contents the data being analyzed -250 * @param source the source name to use when recording the evidence -251 * @param key the key name to use when recording the evidence -252 * @return true if evidence was collected; otherwise false -253 */ -254 private boolean addSummaryInfo(Dependency dependency, Pattern pattern, -255 int group, String contents, String source, String key) { -256 final Matcher matcher = pattern.matcher(contents); -257 final boolean found = matcher.find(); -258 if (found) { -259 JarAnalyzer.addDescription(dependency, matcher.group(group), -260 source, key); -261 } -262 return found; -263 } -264 -265 /** -266 * Collects evidence from the home page URL. -267 * -268 * @param pattern the pattern to match -269 * @param evidence the evidence collection to add the evidence to -270 * @param source the source of the evidence -271 * @param name the name of the evidence -272 * @param contents the home page URL -273 * @return true if evidence was collected; otherwise false -274 */ -275 private boolean gatherHomePageEvidence(Pattern pattern, -276 EvidenceCollection evidence, String source, String name, -277 String contents) { -278 final Matcher matcher = pattern.matcher(contents); -279 boolean found = false; -280 if (matcher.find()) { -281 final String url = matcher.group(4); -282 if (UrlStringUtils.isUrl(url)) { -283 found = true; -284 evidence.addEvidence(source, name, url, Confidence.MEDIUM); -285 } -286 } -287 return found; -288 } -289 -290 /** -291 * Gather evidence from a Python source file using the given string assignment regex pattern. -292 * -293 * @param pattern to scan contents with -294 * @param contents of Python source file -295 * @param source for storing evidence -296 * @param evidence to store evidence in -297 * @param name of evidence -298 * @param confidence in evidence -299 * @return whether evidence was found -300 */ -301 private boolean gatherEvidence(Pattern pattern, String contents, -302 String source, EvidenceCollection evidence, String name, -303 Confidence confidence) { -304 final Matcher matcher = pattern.matcher(contents); -305 final boolean found = matcher.find(); -306 if (found) { -307 evidence.addEvidence(source, name, matcher.group(4), confidence); -308 } -309 return found; -310 } -311 -312 @Override -313 protected String getAnalyzerEnabledSettingKey() { -314 return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED; -315 } -316 } +35 import java.nio.charset.Charset; +36 import java.util.ArrayList; +37 import java.util.List; +38 import java.util.regex.Matcher; +39 import java.util.regex.Pattern; +40 +41 /** +42 * Used to analyze a Python package, and collect information that can be used to +43 * determine the associated CPE. +44 * +45 * @author Dale Visser +46 */ +47 @Experimental +48 public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { +49 +50 /** +51 * Used when compiling file scanning regex patterns. +52 */ +53 private static final int REGEX_OPTIONS = Pattern.DOTALL +54 | Pattern.CASE_INSENSITIVE; +55 +56 /** +57 * Filename extensions for files to be analyzed. +58 */ +59 private static final String EXTENSIONS = "py"; +60 +61 /** +62 * Pattern for matching the module docstring in a source file. +63 */ +64 private static final Pattern MODULE_DOCSTRING = Pattern.compile( +65 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); +66 +67 /** +68 * Matches assignments to version variables in Python source code. +69 */ +70 private static final Pattern VERSION_PATTERN = Pattern.compile( +71 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", +72 REGEX_OPTIONS); +73 +74 /** +75 * Matches assignments to title variables in Python source code. +76 */ +77 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); +78 +79 /** +80 * Matches assignments to summary variables in Python source code. +81 */ +82 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); +83 +84 /** +85 * Matches assignments to URL/URL variables in Python source code. +86 */ +87 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); +88 +89 /** +90 * Matches assignments to home page variables in Python source code. +91 */ +92 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); +93 +94 /** +95 * Matches assignments to author variables in Python source code. +96 */ +97 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); +98 +99 /** +100 * Filter that detects files named "__init__.py". +101 */ +102 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); +103 +104 /** +105 * The file filter for python files. +106 */ +107 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); +108 +109 /** +110 * Returns the name of the Python Package Analyzer. +111 * +112 * @return the name of the analyzer +113 */ +114 @Override +115 public String getName() { +116 return "Python Package Analyzer"; +117 } +118 +119 /** +120 * Tell that we are used for information collection. +121 * +122 * @return INFORMATION_COLLECTION +123 */ +124 @Override +125 public AnalysisPhase getAnalysisPhase() { +126 return AnalysisPhase.INFORMATION_COLLECTION; +127 } +128 +129 /** +130 * The file filter used to determine which files this analyzer supports. +131 */ +132 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +133 +134 /** +135 * Returns the FileFilter +136 * +137 * @return the FileFilter +138 */ +139 @Override +140 protected FileFilter getFileFilter() { +141 return FILTER; +142 } +143 +144 /** +145 * No-op initializer implementation. +146 * +147 * @throws Exception never thrown +148 */ +149 @Override +150 protected void initializeFileTypeAnalyzer() throws Exception { +151 // Nothing to do here. +152 } +153 +154 /** +155 * Utility function to create a regex pattern matcher. +156 * +157 * @param name the value to use when constructing the assignment pattern +158 * @return the compiled Pattern +159 */ +160 private static Pattern compileAssignPattern(String name) { +161 return Pattern.compile( +162 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), +163 REGEX_OPTIONS); +164 } +165 +166 /** +167 * Analyzes python packages and adds evidence to the dependency. +168 * +169 * @param dependency the dependency being analyzed +170 * @param engine the engine being used to perform the scan +171 * @throws AnalysisException thrown if there is an unrecoverable error +172 * analyzing the dependency +173 */ +174 @Override +175 protected void analyzeFileType(Dependency dependency, Engine engine) +176 throws AnalysisException { +177 final File file = dependency.getActualFile(); +178 final File parent = file.getParentFile(); +179 final String parentName = parent.getName(); +180 if (INIT_PY_FILTER.accept(file)) { +181 //by definition, the containing folder of __init__.py is considered the package, even the file is empty: +182 //"The __init__.py files are required to make Python treat the directories as containing packages" +183 //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html; +184 dependency.setDisplayFileName(parentName + "/__init__.py"); +185 dependency.getProductEvidence().addEvidence(file.getName(), +186 "PackageName", parentName, Confidence.HIGHEST); +187 +188 final File[] fileList = parent.listFiles(PY_FILTER); +189 if (fileList != null) { +190 for (final File sourceFile : fileList) { +191 analyzeFileContents(dependency, sourceFile); +192 } +193 } +194 } else { +195 // copy, alter and set in case some other thread is iterating over +196 final List<Dependency> dependencies = new ArrayList<Dependency>( +197 engine.getDependencies()); +198 dependencies.remove(dependency); +199 engine.setDependencies(dependencies); +200 } +201 } +202 +203 /** +204 * This should gather information from leading docstrings, file comments, +205 * and assignments to __version__, __title__, __summary__, __uri__, __url__, +206 * __home*page__, __author__, and their all caps equivalents. +207 * +208 * @param dependency the dependency being analyzed +209 * @param file the file name to analyze +210 * @return whether evidence was found +211 * @throws AnalysisException thrown if there is an unrecoverable error +212 */ +213 private boolean analyzeFileContents(Dependency dependency, File file) +214 throws AnalysisException { +215 String contents; +216 try { +217 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); +218 } catch (IOException e) { +219 throw new AnalysisException( +220 "Problem occurred while reading dependency file.", e); +221 } +222 boolean found = false; +223 if (!contents.isEmpty()) { +224 final String source = file.getName(); +225 found = gatherEvidence(VERSION_PATTERN, contents, source, +226 dependency.getVersionEvidence(), "SourceVersion", +227 Confidence.MEDIUM); +228 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents, +229 source, "summary"); +230 if (INIT_PY_FILTER.accept(file)) { +231 found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2, +232 contents, source, "docstring"); +233 } +234 found |= gatherEvidence(TITLE_PATTERN, contents, source, +235 dependency.getProductEvidence(), "SourceTitle", +236 Confidence.LOW); +237 final EvidenceCollection vendorEvidence = dependency +238 .getVendorEvidence(); +239 found |= gatherEvidence(AUTHOR_PATTERN, contents, source, +240 vendorEvidence, "SourceAuthor", Confidence.MEDIUM); +241 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, +242 source, "URL", contents); +243 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, +244 vendorEvidence, source, "HomePage", contents); +245 } +246 return found; +247 } +248 +249 /** +250 * Adds summary information to the dependency +251 * +252 * @param dependency the dependency being analyzed +253 * @param pattern the pattern used to perform analysis +254 * @param group the group from the pattern that indicates the data to use +255 * @param contents the data being analyzed +256 * @param source the source name to use when recording the evidence +257 * @param key the key name to use when recording the evidence +258 * @return true if evidence was collected; otherwise false +259 */ +260 private boolean addSummaryInfo(Dependency dependency, Pattern pattern, +261 int group, String contents, String source, String key) { +262 final Matcher matcher = pattern.matcher(contents); +263 final boolean found = matcher.find(); +264 if (found) { +265 JarAnalyzer.addDescription(dependency, matcher.group(group), +266 source, key); +267 } +268 return found; +269 } +270 +271 /** +272 * Collects evidence from the home page URL. +273 * +274 * @param pattern the pattern to match +275 * @param evidence the evidence collection to add the evidence to +276 * @param source the source of the evidence +277 * @param name the name of the evidence +278 * @param contents the home page URL +279 * @return true if evidence was collected; otherwise false +280 */ +281 private boolean gatherHomePageEvidence(Pattern pattern, +282 EvidenceCollection evidence, String source, String name, +283 String contents) { +284 final Matcher matcher = pattern.matcher(contents); +285 boolean found = false; +286 if (matcher.find()) { +287 final String url = matcher.group(4); +288 if (UrlStringUtils.isUrl(url)) { +289 found = true; +290 evidence.addEvidence(source, name, url, Confidence.MEDIUM); +291 } +292 } +293 return found; +294 } +295 +296 /** +297 * Gather evidence from a Python source file using the given string +298 * assignment regex pattern. +299 * +300 * @param pattern to scan contents with +301 * @param contents of Python source file +302 * @param source for storing evidence +303 * @param evidence to store evidence in +304 * @param name of evidence +305 * @param confidence in evidence +306 * @return whether evidence was found +307 */ +308 private boolean gatherEvidence(Pattern pattern, String contents, +309 String source, EvidenceCollection evidence, String name, +310 Confidence confidence) { +311 final Matcher matcher = pattern.matcher(contents); +312 final boolean found = matcher.find(); +313 if (found) { +314 evidence.addEvidence(source, name, matcher.group(4), confidence); +315 } +316 return found; +317 } +318 +319 @Override +320 protected String getAnalyzerEnabledSettingKey() { +321 return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED; +322 } +323 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html index 93be2b0d4..d14417ea9 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html @@ -25,329 +25,458 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import org.apache.commons.io.FileUtils; -21 import org.owasp.dependencycheck.Engine; -22 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -23 import org.owasp.dependencycheck.dependency.Confidence; -24 import org.owasp.dependencycheck.dependency.Dependency; -25 import org.owasp.dependencycheck.dependency.Reference; -26 import org.owasp.dependencycheck.dependency.Vulnerability; -27 import org.owasp.dependencycheck.utils.FileFilterBuilder; -28 import org.owasp.dependencycheck.utils.Settings; -29 import org.slf4j.Logger; -30 import org.slf4j.LoggerFactory; -31 -32 import java.io.*; -33 import java.util.*; -34 -35 /** -36 * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party bundle-audit tool. -37 * -38 * @author Dale Visser -39 */ -40 public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { -41 -42 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class); +20 import java.io.BufferedReader; +21 import java.io.File; +22 import java.io.FileFilter; +23 import java.io.IOException; +24 import java.io.InputStreamReader; +25 import java.util.ArrayList; +26 import java.util.HashMap; +27 import java.util.List; +28 import java.util.Map; +29 import java.nio.charset.Charset; +30 import org.apache.commons.io.FileUtils; +31 import org.owasp.dependencycheck.Engine; +32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +33 import org.owasp.dependencycheck.data.nvdcve.CveDB; +34 import org.owasp.dependencycheck.dependency.Confidence; +35 import org.owasp.dependencycheck.dependency.Dependency; +36 import org.owasp.dependencycheck.dependency.Reference; +37 import org.owasp.dependencycheck.dependency.Vulnerability; +38 import org.owasp.dependencycheck.utils.FileFilterBuilder; +39 import org.owasp.dependencycheck.utils.Settings; +40 import org.slf4j.Logger; +41 import org.slf4j.LoggerFactory; +42 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; 43 -44 /** -45 * The name of the analyzer. -46 */ -47 private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer"; -48 -49 /** -50 * The phase that this analyzer is intended to run in. -51 */ -52 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; -53 -54 private static final FileFilter FILTER -55 = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); -56 public static final String NAME = "Name: "; -57 public static final String VERSION = "Version: "; -58 public static final String ADVISORY = "Advisory: "; -59 public static final String CRITICALITY = "Criticality: "; -60 -61 /** -62 * @return a filter that accepts files named Gemfile.lock -63 */ -64 @Override -65 protected FileFilter getFileFilter() { -66 return FILTER; -67 } -68 -69 /** -70 * Launch bundle-audit. -71 * -72 * @return a handle to the process -73 */ -74 private Process launchBundleAudit(File folder) throws AnalysisException { -75 if (!folder.isDirectory()) { -76 throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath())); -77 } -78 final List<String> args = new ArrayList<String>(); -79 final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH); -80 args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath); -81 args.add("check"); -82 args.add("--verbose"); -83 final ProcessBuilder builder = new ProcessBuilder(args); -84 builder.directory(folder); -85 try { -86 LOGGER.info("Launching: " + args + " from " + folder); -87 return builder.start(); -88 } catch (IOException ioe) { -89 throw new AnalysisException("bundle-audit failure", ioe); -90 } -91 } -92 -93 /** -94 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location. -95 * -96 * @throws Exception if anything goes wrong -97 */ -98 @Override -99 public void initializeFileTypeAnalyzer() throws Exception { -100 // Now, need to see if bundle-audit actually runs from this location. -101 Process process = null; -102 try { -103 process = launchBundleAudit(Settings.getTempDirectory()); -104 } -105 catch(AnalysisException ae) { -106 LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME); -107 setEnabled(false); -108 throw ae; -109 } -110 -111 int exitValue = process.waitFor(); -112 if (0 == exitValue) { -113 LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue); -114 setEnabled(false); -115 throw new AnalysisException("Unexpected exit code from bundle-audit process."); -116 } else { -117 BufferedReader reader = null; -118 try { -119 reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); -120 if (!reader.ready()) { -121 LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME); -122 setEnabled(false); -123 throw new AnalysisException("Bundle-audit error stream unexpectedly not ready."); -124 } else { -125 final String line = reader.readLine(); -126 if (line == null || !line.contains("Errno::ENOENT")) { -127 LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line); -128 setEnabled(false); -129 throw new AnalysisException("Unexpected bundle-audit output."); -130 } -131 } -132 } finally { -133 if (null != reader) { -134 reader.close(); -135 } -136 } -137 } -138 -139 if (isEnabled()) { -140 LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " -141 + "occasionally to keep its database up to date."); -142 } -143 } -144 -145 /** -146 * Returns the name of the analyzer. -147 * -148 * @return the name of the analyzer. -149 */ -150 @Override -151 public String getName() { -152 return ANALYZER_NAME; -153 } -154 -155 /** -156 * Returns the phase that the analyzer is intended to run in. -157 * -158 * @return the phase that the analyzer is intended to run in. -159 */ -160 @Override -161 public AnalysisPhase getAnalysisPhase() { -162 return ANALYSIS_PHASE; -163 } -164 -165 /** -166 * Returns the key used in the properties file to reference the analyzer's enabled property. -167 * -168 * @return the analyzer's enabled property setting key -169 */ -170 @Override -171 protected String getAnalyzerEnabledSettingKey() { -172 return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED; -173 } -174 -175 /** -176 * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have successfully initialized, and it will be necessary -177 * to disable {@link RubyGemspecAnalyzer}. -178 */ -179 private boolean needToDisableGemspecAnalyzer = true; -180 -181 @Override -182 protected void analyzeFileType(Dependency dependency, Engine engine) -183 throws AnalysisException { -184 if (needToDisableGemspecAnalyzer) { -185 boolean failed = true; -186 final String className = RubyGemspecAnalyzer.class.getName(); -187 for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) { -188 if (analyzer instanceof RubyGemspecAnalyzer) { -189 ((RubyGemspecAnalyzer) analyzer).setEnabled(false); -190 LOGGER.info("Disabled " + className + " to avoid noisy duplicate results."); -191 failed = false; -192 } -193 } -194 if (failed) { -195 LOGGER.warn("Did not find" + className + '.'); -196 } -197 needToDisableGemspecAnalyzer = false; -198 } -199 final File parentFile = dependency.getActualFile().getParentFile(); -200 final Process process = launchBundleAudit(parentFile); -201 try { -202 process.waitFor(); -203 } catch (InterruptedException ie) { -204 throw new AnalysisException("bundle-audit process interrupted", ie); -205 } -206 BufferedReader rdr = null; -207 try { -208 BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); -209 while(errReader.ready()) { -210 String error = errReader.readLine(); -211 LOGGER.warn(error); -212 } -213 rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); -214 processBundlerAuditOutput(dependency, engine, rdr); -215 } catch (IOException ioe) { -216 LOGGER.warn("bundle-audit failure", ioe); -217 } finally { -218 if (null != rdr) { -219 try { -220 rdr.close(); -221 } catch (IOException ioe) { -222 LOGGER.warn("bundle-audit close failure", ioe); -223 } -224 } -225 } -226 -227 } -228 -229 private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException { -230 final String parentName = original.getActualFile().getParentFile().getName(); -231 final String fileName = original.getFileName(); -232 Dependency dependency = null; -233 Vulnerability vulnerability = null; -234 String gem = null; -235 final Map<String, Dependency> map = new HashMap<String, Dependency>(); -236 boolean appendToDescription = false; -237 while (rdr.ready()) { -238 final String nextLine = rdr.readLine(); -239 if (null == nextLine) { -240 break; -241 } else if (nextLine.startsWith(NAME)) { -242 appendToDescription = false; -243 gem = nextLine.substring(NAME.length()); -244 if (!map.containsKey(gem)) { -245 map.put(gem, createDependencyForGem(engine, parentName, fileName, gem)); -246 } -247 dependency = map.get(gem); -248 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -249 } else if (nextLine.startsWith(VERSION)) { -250 vulnerability = createVulnerability(parentName, dependency, vulnerability, gem, nextLine); -251 } else if (nextLine.startsWith(ADVISORY)) { -252 setVulnerabilityName(parentName, dependency, vulnerability, nextLine); -253 } else if (nextLine.startsWith(CRITICALITY)) { -254 addCriticalityToVulnerability(parentName, vulnerability, nextLine); -255 } else if (nextLine.startsWith("URL: ")) { -256 addReferenceToVulnerability(parentName, vulnerability, nextLine); -257 } else if (nextLine.startsWith("Description:")) { -258 appendToDescription = true; -259 if (null != vulnerability) { -260 vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 indicates unknown). See link below for full details. *** "); -261 } -262 } else if (appendToDescription) { -263 if (null != vulnerability) { -264 vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n"); -265 } -266 } -267 } -268 } -269 -270 private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) { -271 final String advisory = nextLine.substring((ADVISORY.length())); -272 if (null != vulnerability) { -273 vulnerability.setName(advisory); -274 } -275 if (null != dependency) { -276 dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE -277 } -278 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -279 } -280 -281 private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { -282 final String url = nextLine.substring(("URL: ").length()); -283 if (null != vulnerability) { -284 Reference ref = new Reference(); -285 ref.setName(vulnerability.getName()); -286 ref.setSource("bundle-audit"); -287 ref.setUrl(url); -288 vulnerability.getReferences().add(ref); -289 } -290 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -291 } -292 -293 private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { -294 if (null != vulnerability) { -295 final String criticality = nextLine.substring(CRITICALITY.length()).trim(); -296 if ("High".equals(criticality)) { -297 vulnerability.setCvssScore(8.5f); -298 } else if ("Medium".equals(criticality)) { -299 vulnerability.setCvssScore(5.5f); -300 } else if ("Low".equals(criticality)) { -301 vulnerability.setCvssScore(2.0f); -302 } else { -303 vulnerability.setCvssScore(-1.0f); -304 } -305 } -306 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -307 } -308 -309 private Vulnerability createVulnerability(String parentName, Dependency dependency, Vulnerability vulnerability, String gem, String nextLine) { -310 if (null != dependency) { -311 final String version = nextLine.substring(VERSION.length()); -312 dependency.getVersionEvidence().addEvidence( -313 "bundler-audit", -314 "Version", -315 version, -316 Confidence.HIGHEST); -317 vulnerability = new Vulnerability(); // don't add to dependency until we have name set later -318 vulnerability.setMatchedCPE( -319 String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version), -320 null); -321 vulnerability.setCvssAccessVector("-"); -322 vulnerability.setCvssAccessComplexity("-"); -323 vulnerability.setCvssAuthentication("-"); -324 vulnerability.setCvssAvailabilityImpact("-"); -325 vulnerability.setCvssConfidentialityImpact("-"); -326 vulnerability.setCvssIntegrityImpact("-"); -327 } -328 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -329 return vulnerability; -330 } -331 -332 private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String gem) throws IOException { -333 final File tempFile = File.createTempFile("Gemfile-" + gem, ".lock", Settings.getTempDirectory()); -334 final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem); -335 FileUtils.write(tempFile, displayFileName); // unique contents to avoid dependency bundling -336 final Dependency dependency = new Dependency(tempFile); -337 dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST); -338 dependency.setDisplayFileName(displayFileName); -339 engine.getDependencies().add(dependency); -340 return dependency; -341 } -342 } +44 /** +45 * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party +46 * bundle-audit tool. +47 * +48 * @author Dale Visser +49 */ +50 @Experimental +51 public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { +52 +53 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class); +54 +55 /** +56 * The name of the analyzer. +57 */ +58 private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer"; +59 +60 /** +61 * The phase that this analyzer is intended to run in. +62 */ +63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; +64 /** +65 * The filter defining which files will be analyzed. +66 */ +67 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); +68 /** +69 * Name. +70 */ +71 public static final String NAME = "Name: "; +72 /** +73 * Version. +74 */ +75 public static final String VERSION = "Version: "; +76 /** +77 * Advisory. +78 */ +79 public static final String ADVISORY = "Advisory: "; +80 /** +81 * Criticality. +82 */ +83 public static final String CRITICALITY = "Criticality: "; +84 +85 /** +86 * The DAL. +87 */ +88 private CveDB cvedb; +89 +90 /** +91 * @return a filter that accepts files named Gemfile.lock +92 */ +93 @Override +94 protected FileFilter getFileFilter() { +95 return FILTER; +96 } +97 +98 /** +99 * Launch bundle-audit. +100 * +101 * @param folder directory that contains bundle audit +102 * @return a handle to the process +103 * @throws AnalysisException thrown when there is an issue launching bundle +104 * audit +105 */ +106 private Process launchBundleAudit(File folder) throws AnalysisException { +107 if (!folder.isDirectory()) { +108 throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath())); +109 } +110 final List<String> args = new ArrayList<String>(); +111 final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH); +112 args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath); +113 args.add("check"); +114 args.add("--verbose"); +115 final ProcessBuilder builder = new ProcessBuilder(args); +116 builder.directory(folder); +117 try { +118 LOGGER.info("Launching: " + args + " from " + folder); +119 return builder.start(); +120 } catch (IOException ioe) { +121 throw new AnalysisException("bundle-audit failure", ioe); +122 } +123 } +124 +125 /** +126 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a +127 * temporary location. +128 * +129 * @throws Exception if anything goes wrong +130 */ +131 @Override +132 public void initializeFileTypeAnalyzer() throws Exception { +133 try { +134 cvedb = new CveDB(); +135 cvedb.open(); +136 } catch (DatabaseException ex) { +137 LOGGER.warn("Exception opening the database"); +138 LOGGER.debug("error", ex); +139 setEnabled(false); +140 throw ex; +141 } +142 // Now, need to see if bundle-audit actually runs from this location. +143 Process process = null; +144 try { +145 process = launchBundleAudit(Settings.getTempDirectory()); +146 } catch (AnalysisException ae) { +147 LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME); +148 setEnabled(false); +149 cvedb.close(); +150 cvedb = null; +151 throw ae; +152 } +153 +154 final int exitValue = process.waitFor(); +155 if (0 == exitValue) { +156 LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue); +157 setEnabled(false); +158 throw new AnalysisException("Unexpected exit code from bundle-audit process."); +159 } else { +160 BufferedReader reader = null; +161 try { +162 reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); +163 if (!reader.ready()) { +164 LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME); +165 setEnabled(false); +166 throw new AnalysisException("Bundle-audit error stream unexpectedly not ready."); +167 } else { +168 final String line = reader.readLine(); +169 if (line == null || !line.contains("Errno::ENOENT")) { +170 LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line); +171 setEnabled(false); +172 throw new AnalysisException("Unexpected bundle-audit output."); +173 } +174 } +175 } finally { +176 if (null != reader) { +177 reader.close(); +178 } +179 } +180 } +181 +182 if (isEnabled()) { +183 LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " +184 + "occasionally to keep its database up to date."); +185 } +186 } +187 +188 /** +189 * Returns the name of the analyzer. +190 * +191 * @return the name of the analyzer. +192 */ +193 @Override +194 public String getName() { +195 return ANALYZER_NAME; +196 } +197 +198 /** +199 * Returns the phase that the analyzer is intended to run in. +200 * +201 * @return the phase that the analyzer is intended to run in. +202 */ +203 @Override +204 public AnalysisPhase getAnalysisPhase() { +205 return ANALYSIS_PHASE; +206 } +207 +208 /** +209 * Returns the key used in the properties file to reference the analyzer's +210 * enabled property. +211 * +212 * @return the analyzer's enabled property setting key +213 */ +214 @Override +215 protected String getAnalyzerEnabledSettingKey() { +216 return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED; +217 } +218 +219 /** +220 * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have +221 * successfully initialized, and it will be necessary to disable +222 * {@link RubyGemspecAnalyzer}. +223 */ +224 private boolean needToDisableGemspecAnalyzer = true; +225 +226 /** +227 * Determines if the analyzer can analyze the given file type. +228 * +229 * @param dependency the dependency to determine if it can analyze +230 * @param engine the dependency-check engine +231 * @throws AnalysisException thrown if there is an analysis exception. +232 */ +233 @Override +234 protected void analyzeFileType(Dependency dependency, Engine engine) +235 throws AnalysisException { +236 if (needToDisableGemspecAnalyzer) { +237 boolean failed = true; +238 final String className = RubyGemspecAnalyzer.class.getName(); +239 for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) { +240 if (analyzer instanceof RubyBundlerAnalyzer) { +241 ((RubyBundlerAnalyzer) analyzer).setEnabled(false); +242 LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results."); +243 } else if (analyzer instanceof RubyGemspecAnalyzer) { +244 ((RubyGemspecAnalyzer) analyzer).setEnabled(false); +245 LOGGER.info("Disabled " + className + " to avoid noisy duplicate results."); +246 failed = false; +247 } +248 } +249 if (failed) { +250 LOGGER.warn("Did not find " + className + '.'); +251 } +252 needToDisableGemspecAnalyzer = false; +253 } +254 final File parentFile = dependency.getActualFile().getParentFile(); +255 final Process process = launchBundleAudit(parentFile); +256 try { +257 process.waitFor(); +258 } catch (InterruptedException ie) { +259 throw new AnalysisException("bundle-audit process interrupted", ie); +260 } +261 BufferedReader rdr = null; +262 BufferedReader errReader = null; +263 try { +264 errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); +265 while (errReader.ready()) { +266 final String error = errReader.readLine(); +267 LOGGER.warn(error); +268 } +269 rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); +270 processBundlerAuditOutput(dependency, engine, rdr); +271 } catch (IOException ioe) { +272 LOGGER.warn("bundle-audit failure", ioe); +273 } finally { +274 if (errReader != null) { +275 try { +276 errReader.close(); +277 } catch (IOException ioe) { +278 LOGGER.warn("bundle-audit close failure", ioe); +279 } +280 } +281 if (null != rdr) { +282 try { +283 rdr.close(); +284 } catch (IOException ioe) { +285 LOGGER.warn("bundle-audit close failure", ioe); +286 } +287 } +288 } +289 +290 } +291 +292 /** +293 * Processes the bundler audit output. +294 * +295 * @param original the dependency +296 * @param engine the dependency-check engine +297 * @param rdr the reader of the report +298 * @throws IOException thrown if the report cannot be read. +299 */ +300 private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException { +301 final String parentName = original.getActualFile().getParentFile().getName(); +302 final String fileName = original.getFileName(); +303 final String filePath = original.getFilePath(); +304 Dependency dependency = null; +305 Vulnerability vulnerability = null; +306 String gem = null; +307 final Map<String, Dependency> map = new HashMap<String, Dependency>(); +308 boolean appendToDescription = false; +309 while (rdr.ready()) { +310 final String nextLine = rdr.readLine(); +311 if (null == nextLine) { +312 break; +313 } else if (nextLine.startsWith(NAME)) { +314 appendToDescription = false; +315 gem = nextLine.substring(NAME.length()); +316 if (!map.containsKey(gem)) { +317 map.put(gem, createDependencyForGem(engine, parentName, fileName, filePath, gem)); +318 } +319 dependency = map.get(gem); +320 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +321 } else if (nextLine.startsWith(VERSION)) { +322 vulnerability = createVulnerability(parentName, dependency, gem, nextLine); +323 } else if (nextLine.startsWith(ADVISORY)) { +324 setVulnerabilityName(parentName, dependency, vulnerability, nextLine); +325 } else if (nextLine.startsWith(CRITICALITY)) { +326 addCriticalityToVulnerability(parentName, vulnerability, nextLine); +327 } else if (nextLine.startsWith("URL: ")) { +328 addReferenceToVulnerability(parentName, vulnerability, nextLine); +329 } else if (nextLine.startsWith("Description:")) { +330 appendToDescription = true; +331 if (null != vulnerability) { +332 vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. " +333 + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 " +334 + " indicates unknown). See link below for full details. *** "); +335 } +336 } else if (appendToDescription) { +337 if (null != vulnerability) { +338 vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n"); +339 } +340 } +341 } +342 } +343 +344 /** +345 * Sets the vulnerability name. +346 * +347 * @param parentName the parent name +348 * @param dependency the dependency +349 * @param vulnerability the vulnerability +350 * @param nextLine the line to parse +351 */ +352 private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) { +353 final String advisory = nextLine.substring((ADVISORY.length())); +354 if (null != vulnerability) { +355 vulnerability.setName(advisory); +356 } +357 if (null != dependency) { +358 dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE +359 } +360 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +361 } +362 +363 /** +364 * Adds a reference to the vulnerability. +365 * +366 * @param parentName the parent name +367 * @param vulnerability the vulnerability +368 * @param nextLine the line to parse +369 */ +370 private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { +371 final String url = nextLine.substring(("URL: ").length()); +372 if (null != vulnerability) { +373 final Reference ref = new Reference(); +374 ref.setName(vulnerability.getName()); +375 ref.setSource("bundle-audit"); +376 ref.setUrl(url); +377 vulnerability.getReferences().add(ref); +378 } +379 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +380 } +381 +382 /** +383 * Adds the criticality to the vulnerability +384 * +385 * @param parentName the parent name +386 * @param vulnerability the vulnerability +387 * @param nextLine the line to parse +388 */ +389 private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { +390 if (null != vulnerability) { +391 final String criticality = nextLine.substring(CRITICALITY.length()).trim(); +392 float score = -1.0f; +393 Vulnerability v = null; +394 try { +395 v = cvedb.getVulnerability(vulnerability.getName()); +396 } catch (DatabaseException ex) { +397 LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName()); +398 } +399 if (v != null) { +400 score = v.getCvssScore(); +401 } else if ("High".equalsIgnoreCase(criticality)) { +402 score = 8.5f; +403 } else if ("Medium".equalsIgnoreCase(criticality)) { +404 score = 5.5f; +405 } else if ("Low".equalsIgnoreCase(criticality)) { +406 score = 2.0f; +407 } +408 vulnerability.setCvssScore(score); +409 } +410 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +411 } +412 +413 /** +414 * Creates a vulnerability. +415 * +416 * @param parentName the parent name +417 * @param dependency the dependency +418 * @param gem the gem name +419 * @param nextLine the line to parse +420 * @return the vulnerability +421 */ +422 private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) { +423 Vulnerability vulnerability = null; +424 if (null != dependency) { +425 final String version = nextLine.substring(VERSION.length()); +426 dependency.getVersionEvidence().addEvidence( +427 "bundler-audit", +428 "Version", +429 version, +430 Confidence.HIGHEST); +431 vulnerability = new Vulnerability(); // don't add to dependency until we have name set later +432 vulnerability.setMatchedCPE( +433 String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version), +434 null); +435 vulnerability.setCvssAccessVector("-"); +436 vulnerability.setCvssAccessComplexity("-"); +437 vulnerability.setCvssAuthentication("-"); +438 vulnerability.setCvssAvailabilityImpact("-"); +439 vulnerability.setCvssConfidentialityImpact("-"); +440 vulnerability.setCvssIntegrityImpact("-"); +441 } +442 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +443 return vulnerability; +444 } +445 +446 /** +447 * Creates the dependency based off of the gem. +448 * +449 * @param engine the engine used for scanning +450 * @param parentName the gem parent +451 * @param fileName the file name +452 * @param filePath the file path +453 * @param gem the gem name +454 * @return the dependency to add +455 * @throws IOException thrown if a temporary gem file could not be written +456 */ +457 private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException { +458 final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock"); +459 gemFile.createNewFile(); +460 final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem); +461 +462 FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling +463 final Dependency dependency = new Dependency(gemFile); +464 dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST); +465 dependency.setDisplayFileName(displayFileName); +466 dependency.setFileName(fileName); +467 dependency.setFilePath(filePath); +468 engine.getDependencies().add(dependency); +469 return dependency; +470 } +471 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html new file mode 100644 index 000000000..127f09633 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html @@ -0,0 +1,152 @@ + + + +RubyBundlerAnalyzer xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +3    *
      +4    * Licensed under the Apache License, Version 2.0 (the "License");
      +5    * you may not use this file except in compliance with the License.
      +6    * You may obtain a copy of the License at
      +7    *
      +8    *     http://www.apache.org/licenses/LICENSE-2.0
      +9    *
      +10   * Unless required by applicable law or agreed to in writing, software
      +11   * distributed under the License is distributed on an "AS IS" BASIS,
      +12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      +13   * See the License for the specific language governing permissions and
      +14   * limitations under the License.
      +15   *
      +16   * Copyright (c) 2016 Bianca Jiang. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.analyzer;
      +19  
      +20  import java.io.File;
      +21  import java.io.FilenameFilter;
      +22  
      +23  import org.owasp.dependencycheck.Engine;
      +24  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      +25  import org.owasp.dependencycheck.dependency.Dependency;
      +26  
      +27  /**
      +28   * This analyzer accepts the fully resolved .gemspec created by the Ruby bundler
      +29   * (http://bundler.io) for better evidence results. It also tries to resolve the
      +30   * dependency packagePath to where the gem is actually installed. Then during {@link org.owasp.dependencycheck.analyzer.AnalysisPhase#PRE_FINDING_ANALYSIS}
      +31   * {@link DependencyBundlingAnalyzer} will merge two .gemspec dependencies
      +32   * together if <code>Dependency.getPackagePath()</code> are the same.
      +33   *
      +34   * Ruby bundler creates new .gemspec files under a folder called
      +35   * "specifications" at deploy time, in addition to the original .gemspec files
      +36   * from source. The bundler generated .gemspec files always contain fully
      +37   * resolved attributes thus provide more accurate evidences, whereas the
      +38   * original .gemspec from source often contain variables for attributes that
      +39   * can't be used for evidences.
      +40   *
      +41   * Note this analyzer share the same
      +42   * {@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_RUBY_GEMSPEC_ENABLED} as
      +43   * {@link RubyGemspecAnalyzer}, so it will enabled/disabled with
      +44   * {@link RubyGemspecAnalyzer}.
      +45   *
      +46   * @author Bianca Jiang (biancajiang@gmail.com)
      +47   */
      +48  @Experimental
      +49  public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
      +50  
      +51      /**
      +52       * The name of the analyzer.
      +53       */
      +54      private static final String ANALYZER_NAME = "Ruby Bundler Analyzer";
      +55  
      +56      /**
      +57       * Folder name that contains .gemspec files created by "bundle install"
      +58       */
      +59      private static final String SPECIFICATIONS = "specifications";
      +60  
      +61      /**
      +62       * Folder name that contains the gems by "bundle install"
      +63       */
      +64      private static final String GEMS = "gems";
      +65  
      +66      /**
      +67       * Returns the name of the analyzer.
      +68       *
      +69       * @return the name of the analyzer.
      +70       */
      +71      @Override
      +72      public String getName() {
      +73          return ANALYZER_NAME;
      +74      }
      +75  
      +76      /**
      +77       * Only accept *.gemspec files generated by "bundle install --deployment"
      +78       * under "specifications" folder.
      +79       *
      +80       * @param pathname the path name to test
      +81       * @return true if the analyzer can process the given file; otherwise false
      +82       */
      +83      @Override
      +84      public boolean accept(File pathname) {
      +85  
      +86          boolean accepted = super.accept(pathname);
      +87          if (accepted) {
      +88              final File parentDir = pathname.getParentFile();
      +89              accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
      +90          }
      +91  
      +92          return accepted;
      +93      }
      +94  
      +95      @Override
      +96      protected void analyzeFileType(Dependency dependency, Engine engine)
      +97              throws AnalysisException {
      +98          super.analyzeFileType(dependency, engine);
      +99  
      +100         //find the corresponding gem folder for this .gemspec stub by "bundle install --deployment"
      +101         final File gemspecFile = dependency.getActualFile();
      +102         final String gemFileName = gemspecFile.getName();
      +103         final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec"));
      +104         final File specificationsDir = gemspecFile.getParentFile();
      +105         if (specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
      +106             final File parentDir = specificationsDir.getParentFile();
      +107             if (parentDir != null && parentDir.exists()) {
      +108                 final File gemsDir = new File(parentDir, GEMS);
      +109                 if (gemsDir.exists()) {
      +110                     final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
      +111                         public boolean accept(File dir, String name) {
      +112                             return name.equals(gemName);
      +113                         }
      +114                     });
      +115 
      +116                     if (matchingFiles != null && matchingFiles.length > 0) {
      +117                         final String gemPath = matchingFiles[0].getAbsolutePath();
      +118                         if (dependency.getActualFilePath().equals(dependency.getFilePath())) {
      +119                             if (gemPath != null) {
      +120                                 dependency.setPackagePath(gemPath);
      +121                             }
      +122                         } else {
      +123                             //.gemspec's actualFilePath and filePath are different when it's from a compressed file
      +124                             //in which case actualFilePath is the temp directory used by decompression.
      +125                             //packagePath should use the filePath of the identified gem file in "gems" folder
      +126                             final File gemspecStub = new File(dependency.getFilePath());
      +127                             final File specDir = gemspecStub.getParentFile();
      +128                             if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
      +129                                 final File gemsDir2 = new File(specDir.getParentFile(), GEMS);
      +130                                 final File packageDir = new File(gemsDir2, gemName);
      +131                                 dependency.setPackagePath(packageDir.getAbsolutePath());
      +132                             }
      +133                         }
      +134                     }
      +135                 }
      +136             }
      +137         }
      +138     }
      +139 }
      +
      +
      + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html index e648568bb..df6c70dd1 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html @@ -25,148 +25,231 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import org.apache.commons.io.FileUtils; -21 import org.owasp.dependencycheck.Engine; -22 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -23 import org.owasp.dependencycheck.dependency.Confidence; -24 import org.owasp.dependencycheck.dependency.Dependency; -25 import org.owasp.dependencycheck.dependency.EvidenceCollection; -26 import org.owasp.dependencycheck.utils.FileFilterBuilder; -27 import org.owasp.dependencycheck.utils.Settings; +20 import java.io.File; +21 import java.io.FileFilter; +22 import java.io.FilenameFilter; +23 import java.io.IOException; +24 import java.nio.charset.Charset; +25 import java.util.List; +26 import java.util.regex.Matcher; +27 import java.util.regex.Pattern; 28 -29 import java.io.FileFilter; -30 import java.io.IOException; -31 import java.util.regex.Matcher; -32 import java.util.regex.Pattern; -33 -34 /** -35 * Used to analyze Ruby Gem specifications and collect information that can be used to determine the associated CPE. Regular -36 * expressions are used to parse the well-defined Ruby syntax that forms the specification. -37 * -38 * @author Dale Visser -39 */ -40 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { -41 -42 /** -43 * The name of the analyzer. -44 */ -45 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer"; -46 -47 /** -48 * The phase that this analyzer is intended to run in. -49 */ -50 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -51 -52 private static final String GEMSPEC = "gemspec"; -53 -54 private static final FileFilter FILTER -55 = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); -56 -57 private static final String EMAIL = "email"; +29 import org.apache.commons.io.FileUtils; +30 import org.owasp.dependencycheck.Engine; +31 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +32 import org.owasp.dependencycheck.dependency.Confidence; +33 import org.owasp.dependencycheck.dependency.Dependency; +34 import org.owasp.dependencycheck.dependency.EvidenceCollection; +35 import org.owasp.dependencycheck.utils.FileFilterBuilder; +36 import org.owasp.dependencycheck.utils.Settings; +37 import org.slf4j.Logger; +38 import org.slf4j.LoggerFactory; +39 +40 /** +41 * Used to analyze Ruby Gem specifications and collect information that can be +42 * used to determine the associated CPE. Regular expressions are used to parse +43 * the well-defined Ruby syntax that forms the specification. +44 * +45 * @author Dale Visser +46 */ +47 @Experimental +48 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { +49 +50 /** +51 * The logger. +52 */ +53 private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class); +54 /** +55 * The name of the analyzer. +56 */ +57 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer"; 58 59 /** -60 * @return a filter that accepts files named Rakefile or matching the glob pattern, *.gemspec +60 * The phase that this analyzer is intended to run in. 61 */ -62 @Override -63 protected FileFilter getFileFilter() { -64 return FILTER; -65 } -66 -67 @Override -68 protected void initializeFileTypeAnalyzer() throws Exception { -69 // NO-OP -70 } -71 -72 /** -73 * Returns the name of the analyzer. -74 * -75 * @return the name of the analyzer. -76 */ -77 @Override -78 public String getName() { -79 return ANALYZER_NAME; -80 } +62 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +63 +64 /** +65 * The gemspec file extension. +66 */ +67 private static final String GEMSPEC = "gemspec"; +68 +69 /** +70 * The file filter containing the list of file extensions that can be +71 * analyzed. +72 */ +73 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build(); +74 //TODO: support Rakefile +75 //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); +76 +77 /** +78 * The name of the version file. +79 */ +80 private static final String VERSION_FILE_NAME = "VERSION"; 81 82 /** -83 * Returns the phase that the analyzer is intended to run in. -84 * -85 * @return the phase that the analyzer is intended to run in. -86 */ -87 @Override -88 public AnalysisPhase getAnalysisPhase() { -89 return ANALYSIS_PHASE; -90 } -91 -92 /** -93 * Returns the key used in the properties file to reference the analyzer's enabled property. -94 * -95 * @return the analyzer's enabled property setting key -96 */ -97 @Override -98 protected String getAnalyzerEnabledSettingKey() { -99 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; -100 } -101 -102 /** -103 * The capture group #1 is the block variable. -104 */ -105 private static final Pattern GEMSPEC_BLOCK_INIT -106 = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); -107 -108 @Override -109 protected void analyzeFileType(Dependency dependency, Engine engine) -110 throws AnalysisException { -111 String contents; -112 try { -113 contents = FileUtils.readFileToString(dependency.getActualFile()); -114 } catch (IOException e) { -115 throw new AnalysisException( -116 "Problem occurred while reading dependency file.", e); -117 } -118 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); -119 if (matcher.find()) { -120 contents = contents.substring(matcher.end()); -121 final String blockVariable = matcher.group(1); -122 final EvidenceCollection vendor = dependency.getVendorEvidence(); -123 addStringEvidence(vendor, contents, blockVariable, "author", Confidence.HIGHEST); -124 addListEvidence(vendor, contents, blockVariable, "authors", Confidence.HIGHEST); -125 final String email = addStringEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM); -126 if (email.isEmpty()) { -127 addListEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM); -128 } -129 addStringEvidence(vendor, contents, blockVariable, "homepage", Confidence.MEDIUM); -130 final EvidenceCollection product = dependency.getProductEvidence(); -131 final String name = addStringEvidence(product, contents, blockVariable, "name", Confidence.HIGHEST); -132 if (!name.isEmpty()) { -133 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); -134 } -135 addStringEvidence(product, contents, blockVariable, "summary", Confidence.LOW); -136 addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", Confidence.HIGHEST); -137 } -138 } -139 -140 private void addListEvidence(EvidenceCollection evidences, String contents, -141 String blockVariable, String field, Confidence confidence) { -142 final Matcher matcher = Pattern.compile( -143 String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents); -144 if (matcher.find()) { -145 final String value = matcher.group(1).replaceAll("['\"]", " ").trim(); -146 evidences.addEvidence(GEMSPEC, field, value, confidence); -147 } -148 } -149 -150 private String addStringEvidence(EvidenceCollection evidences, String contents, -151 String blockVariable, String field, Confidence confidence) { -152 final Matcher matcher = Pattern.compile( -153 String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents); -154 String value = ""; -155 if (matcher.find()) { -156 value = matcher.group(2); -157 evidences.addEvidence(GEMSPEC, field, value, confidence); -158 } -159 return value; -160 } -161 } +83 * @return a filter that accepts files matching the glob pattern, *.gemspec +84 */ +85 @Override +86 protected FileFilter getFileFilter() { +87 return FILTER; +88 } +89 +90 @Override +91 protected void initializeFileTypeAnalyzer() throws Exception { +92 // NO-OP +93 } +94 +95 /** +96 * Returns the name of the analyzer. +97 * +98 * @return the name of the analyzer. +99 */ +100 @Override +101 public String getName() { +102 return ANALYZER_NAME; +103 } +104 +105 /** +106 * Returns the phase that the analyzer is intended to run in. +107 * +108 * @return the phase that the analyzer is intended to run in. +109 */ +110 @Override +111 public AnalysisPhase getAnalysisPhase() { +112 return ANALYSIS_PHASE; +113 } +114 +115 /** +116 * Returns the key used in the properties file to reference the analyzer's +117 * enabled property. +118 * +119 * @return the analyzer's enabled property setting key +120 */ +121 @Override +122 protected String getAnalyzerEnabledSettingKey() { +123 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; +124 } +125 +126 /** +127 * The capture group #1 is the block variable. +128 */ +129 private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); +130 +131 @Override +132 protected void analyzeFileType(Dependency dependency, Engine engine) +133 throws AnalysisException { +134 String contents; +135 try { +136 contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset()); +137 } catch (IOException e) { +138 throw new AnalysisException( +139 "Problem occurred while reading dependency file.", e); +140 } +141 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); +142 if (matcher.find()) { +143 contents = contents.substring(matcher.end()); +144 final String blockVariable = matcher.group(1); +145 +146 final EvidenceCollection vendor = dependency.getVendorEvidence(); +147 final EvidenceCollection product = dependency.getProductEvidence(); +148 final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST); +149 if (!name.isEmpty()) { +150 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); +151 } +152 addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.LOW); +153 +154 addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST); +155 addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM); +156 addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST); +157 addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST); +158 +159 final String value = addStringEvidence(dependency.getVersionEvidence(), contents, +160 blockVariable, "version", "version", Confidence.HIGHEST); +161 if (value.length() < 1) { +162 addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence()); +163 } +164 } +165 +166 setPackagePath(dependency); +167 } +168 +169 /** +170 * Adds the specified evidence to the given evidence collection. +171 * +172 * @param evidences the collection to add the evidence to +173 * @param contents the evidence contents +174 * @param blockVariable the variable +175 * @param field the field +176 * @param fieldPattern the field pattern +177 * @param confidence the confidence of the evidence +178 * @return the evidence string value added +179 */ +180 private String addStringEvidence(EvidenceCollection evidences, String contents, +181 String blockVariable, String field, String fieldPattern, Confidence confidence) { +182 String value = ""; +183 +184 //capture array value between [ ] +185 final Matcher arrayMatcher = Pattern.compile( +186 String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); +187 if (arrayMatcher.find()) { +188 final String arrayValue = arrayMatcher.group(1); +189 value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes +190 } else { //capture single value between quotes +191 final Matcher matcher = Pattern.compile( +192 String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); +193 if (matcher.find()) { +194 value = matcher.group(2); +195 } +196 } +197 if (value.length() > 0) { +198 evidences.addEvidence(GEMSPEC, field, value, confidence); +199 } +200 +201 return value; +202 } +203 +204 /** +205 * Adds evidence from the version file. +206 * +207 * @param dependencyFile the dependency being analyzed +208 * @param versionEvidences the version evidence +209 */ +210 private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) { +211 final File parentDir = dependencyFile.getParentFile(); +212 if (parentDir != null) { +213 final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() { +214 public boolean accept(File dir, String name) { +215 return name.contains(VERSION_FILE_NAME); +216 } +217 }); +218 for (File f : matchingFiles) { +219 try { +220 final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset()); +221 if (lines.size() == 1) { //TODO other checking? +222 final String value = lines.get(0).trim(); +223 versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH); +224 } +225 } catch (IOException e) { +226 LOGGER.debug("Error reading gemspec", e); +227 } +228 } +229 } +230 } +231 +232 /** +233 * Sets the package path on the dependency. +234 * +235 * @param dep the dependency to alter +236 */ +237 private void setPackagePath(Dependency dep) { +238 final File file = new File(dep.getFilePath()); +239 final String parent = file.getParent(); +240 if (parent != null) { +241 dep.setPackagePath(parent); +242 } +243 } +244 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html index ce3f75470..0ef1c1648 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html index 341d1b0c3..6a647307f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-frame.html index 3f69b68d2..4886b4567 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer @@ -62,6 +62,9 @@
    74. DependencyBundlingAnalyzer +
    75. +
    76. + Experimental
    77. FalsePositiveAnalyzer @@ -107,6 +110,9 @@
    78. RubyBundleAuditAnalyzer +
    79. +
    80. + RubyBundlerAnalyzer
    81. RubyGemspecAnalyzer diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-summary.html index dc55d48d1..0246e91fd 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer @@ -114,6 +114,11 @@
    82. + + + + + + - + - + - + - + - + - + - + - - + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + + + - - + - + - + - + - + - + - + - - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + + - + - + - + - + - + - + - + - - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - + + + + + + - + - + - + - + - + - - - - + + + + - + - - + + - + - + - + - + - + - + - + - + - + - - + + + - + - + - + - - - - - - + + + + + + - - - - + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - + + + + + + + + + + + + + - - + - + - + + + - - + - + - + - + - + - + - + - + - + - - + - + - + - + - + - - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - + + + + + + + + + + + - + - + - + - + - + - + - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - + - - - - + + + + + + + - - - - - - - - + + - + - - - - - + + + - - - + + + + + + + - - - - - - - + + + + + + + + + + + + @@ -823,1077 +827,1142 @@ - + - + - + - + - + - + - - - - - + + + - - - - - + + + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - + - + - + - - + + + - + - + - + - - - - - - + + + + + - + - + - + - + - + - + - - - - + + + + - + - + - + - + - + - + - + - - - - - - - + + + + + + + + + + + + - - - + + + + + - - - - - - - - - - - - - - - - - - - - + + + + - - - + - + - - - + + + - - + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + - + - + + + + + - + - - + + - - - + + + + - - - - - - - + + + + + + + + + + + + + - + - - - - - - - - + + + + + + + + + + + - - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + - - - - - - - - - - - - - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - + + + + + - - + + + - - + + + - - - - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - + + - + + + + + + - - - - - - - - - + + + + + - + - - + - + + + + + + + + + + + + + + + + - - - + + + - - - - - + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + - - + + - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + - - - - - - - - - - - - - - - - + + + + + + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + + + + + + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      DependencyBundlingAnalyzer
      + Experimental +
      @@ -189,6 +194,11 @@ RubyBundleAuditAnalyzer
      + RubyBundlerAnalyzer +
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-frame.html index a70c3d199..66473098d 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.central diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-summary.html index 6046e2c35..afa169c0c 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.central diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-frame.html index ff20887ce..0cf703955 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.composer diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-summary.html index b4f821391..730cfe15a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.composer diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-frame.html index b032e2597..5aed3dd6e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-summary.html index 8fe9e4630..c993f29ab 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-frame.html index 7b88bcf63..053b3bf11 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-summary.html index fe678a295..f270ed630 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-frame.html index ad521bc4e..8194a67dd 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-summary.html index 298aa1edb..9f8ebb524 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-frame.html index 1aee7e778..8e76c076e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-summary.html index 4ca282c71..8c455c5b3 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-frame.html index fa1ddf464..3e6f62531 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-summary.html index 689676322..ceb4dc04a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html index 4268d8f7f..c9c5d0eef 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html @@ -77,731 +77,786 @@ 69 private ResourceBundle statementBundle = null; 70 71 /** -72 * Creates a new CveDB object and opens the database connection. Note, the connection must be closed by the caller by calling -73 * the close method. -74 * -75 * @throws DatabaseException thrown if there is an exception opening the database. +72 * Creates a new CveDB object and opens the database +73 * connection. Note, the connection must be closed by the caller by calling +74 * the close method. ======= Does the underlying connection support batch +75 * operations? 76 */ -77 public CveDB() throws DatabaseException { -78 super(); -79 try { -80 open(); -81 try { -82 final String databaseProductName = conn.getMetaData().getDatabaseProductName(); -83 LOGGER.debug("Database dialect: {}", databaseProductName); -84 final Locale dbDialect = new Locale(databaseProductName); -85 statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect); -86 } catch (SQLException se) { -87 LOGGER.warn("Problem loading database specific dialect!", se); -88 statementBundle = ResourceBundle.getBundle("data/dbStatements"); -89 } -90 databaseProperties = new DatabaseProperties(this); -91 } catch (DatabaseException ex) { -92 throw ex; -93 } -94 } -95 -96 /** -97 * Returns the database connection. -98 * -99 * @return the database connection -100 */ -101 protected Connection getConnection() { -102 return conn; -103 } -104 -105 /** -106 * Opens the database connection. If the database does not exist, it will create a new one. -107 * -108 * @throws DatabaseException thrown if there is an error opening the database connection -109 */ -110 public final void open() throws DatabaseException { -111 if (!isOpen()) { -112 conn = ConnectionFactory.getConnection(); -113 } -114 } -115 -116 /** -117 * Closes the DB4O database. Close should be called on this object when it is done being used. -118 */ -119 public void close() { -120 if (conn != null) { -121 try { -122 conn.close(); -123 } catch (SQLException ex) { -124 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); -125 LOGGER.debug("", ex); -126 } catch (Throwable ex) { -127 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); -128 LOGGER.debug("", ex); -129 } -130 conn = null; -131 } -132 } -133 -134 /** -135 * Returns whether the database connection is open or closed. -136 * -137 * @return whether the database connection is open or closed -138 */ -139 public boolean isOpen() { -140 return conn != null; -141 } -142 -143 /** -144 * Commits all completed transactions. -145 * -146 * @throws SQLException thrown if a SQL Exception occurs -147 */ -148 public void commit() throws SQLException { -149 //temporary remove this as autocommit is on. -150 //if (conn != null) { -151 // conn.commit(); -152 //} -153 } -154 -155 /** -156 * Cleans up the object and ensures that "close" has been called. -157 * -158 * @throws Throwable thrown if there is a problem -159 */ -160 @Override -161 @SuppressWarnings("FinalizeDeclaration") -162 protected void finalize() throws Throwable { -163 LOGGER.debug("Entering finalize"); -164 close(); -165 super.finalize(); +77 private boolean batchSupported; +78 +79 /** +80 * Creates a new CveDB object and opens the database connection. Note, the +81 * connection must be closed by the caller by calling the close method. +82 * +83 * @throws DatabaseException thrown if there is an exception opening the +84 * database. +85 */ +86 public CveDB() throws DatabaseException { +87 super(); +88 try { +89 open(); +90 try { +91 final String databaseProductName = conn.getMetaData().getDatabaseProductName(); +92 batchSupported = conn.getMetaData().supportsBatchUpdates(); +93 LOGGER.debug("Database dialect: {}", databaseProductName); +94 final Locale dbDialect = new Locale(databaseProductName); +95 statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect); +96 } catch (SQLException se) { +97 LOGGER.warn("Problem loading database specific dialect!", se); +98 statementBundle = ResourceBundle.getBundle("data/dbStatements"); +99 } +100 databaseProperties = new DatabaseProperties(this); +101 } catch (DatabaseException ex) { +102 throw ex; +103 } +104 } +105 +106 /** +107 * Returns the database connection. +108 * +109 * @return the database connection +110 */ +111 protected Connection getConnection() { +112 return conn; +113 } +114 +115 /** +116 * Opens the database connection. If the database does not exist, it will +117 * create a new one. +118 * +119 * @throws DatabaseException thrown if there is an error opening the +120 * database connection +121 */ +122 public final void open() throws DatabaseException { +123 if (!isOpen()) { +124 conn = ConnectionFactory.getConnection(); +125 } +126 } +127 +128 /** +129 * Closes the DB4O database. Close should be called on this object when it +130 * is done being used. +131 */ +132 public void close() { +133 if (conn != null) { +134 try { +135 conn.close(); +136 } catch (SQLException ex) { +137 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); +138 LOGGER.debug("", ex); +139 } catch (Throwable ex) { +140 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); +141 LOGGER.debug("", ex); +142 } +143 conn = null; +144 } +145 } +146 +147 /** +148 * Returns whether the database connection is open or closed. +149 * +150 * @return whether the database connection is open or closed +151 */ +152 public boolean isOpen() { +153 return conn != null; +154 } +155 +156 /** +157 * Commits all completed transactions. +158 * +159 * @throws SQLException thrown if a SQL Exception occurs +160 */ +161 public void commit() throws SQLException { +162 //temporary remove this as autocommit is on. +163 //if (conn != null) { +164 // conn.commit(); +165 //} 166 } -167 /** -168 * Database properties object containing the 'properties' from the database table. -169 */ -170 private DatabaseProperties databaseProperties; -171 -172 /** -173 * Get the value of databaseProperties. -174 * -175 * @return the value of databaseProperties -176 */ -177 public DatabaseProperties getDatabaseProperties() { -178 return databaseProperties; +167 +168 /** +169 * Cleans up the object and ensures that "close" has been called. +170 * +171 * @throws Throwable thrown if there is a problem +172 */ +173 @Override +174 @SuppressWarnings("FinalizeDeclaration") +175 protected void finalize() throws Throwable { +176 LOGGER.debug("Entering finalize"); +177 close(); +178 super.finalize(); 179 } -180 -181 /** -182 * Searches the CPE entries in the database and retrieves all entries for a given vendor and product combination. The returned -183 * list will include all versions of the product that are registered in the NVD CVE data. -184 * -185 * @param vendor the identified vendor name of the dependency being analyzed -186 * @param product the identified name of the product of the dependency being analyzed -187 * @return a set of vulnerable software -188 */ -189 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { -190 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); -191 ResultSet rs = null; -192 PreparedStatement ps = null; -193 try { -194 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); -195 ps.setString(1, vendor); -196 ps.setString(2, product); -197 rs = ps.executeQuery(); -198 -199 while (rs.next()) { -200 final VulnerableSoftware vs = new VulnerableSoftware(); -201 vs.setCpe(rs.getString(1)); -202 cpe.add(vs); -203 } -204 } catch (SQLException ex) { -205 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -206 LOGGER.debug("", ex); -207 } finally { -208 DBUtils.closeResultSet(rs); -209 DBUtils.closeStatement(ps); -210 } -211 return cpe; -212 } -213 -214 /** -215 * Returns the entire list of vendor/product combinations. -216 * -217 * @return the entire list of vendor/product combinations -218 * @throws DatabaseException thrown when there is an error retrieving the data from the DB -219 */ -220 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { -221 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); -222 ResultSet rs = null; -223 PreparedStatement ps = null; -224 try { -225 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); -226 rs = ps.executeQuery(); -227 while (rs.next()) { -228 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); -229 } -230 } catch (SQLException ex) { -231 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; -232 throw new DatabaseException(msg, ex); -233 } finally { -234 DBUtils.closeResultSet(rs); -235 DBUtils.closeStatement(ps); -236 } -237 return data; -238 } -239 -240 /** -241 * Returns a set of properties. -242 * -243 * @return the properties from the database -244 */ -245 Properties getProperties() { -246 final Properties prop = new Properties(); -247 PreparedStatement ps = null; -248 ResultSet rs = null; -249 try { -250 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); -251 rs = ps.executeQuery(); -252 while (rs.next()) { -253 prop.setProperty(rs.getString(1), rs.getString(2)); -254 } -255 } catch (SQLException ex) { -256 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -257 LOGGER.debug("", ex); -258 } finally { -259 DBUtils.closeStatement(ps); -260 DBUtils.closeResultSet(rs); -261 } -262 return prop; -263 } -264 -265 /** -266 * Saves a property to the database. -267 * -268 * @param key the property key -269 * @param value the property value -270 */ -271 void saveProperty(String key, String value) { -272 try { -273 try { -274 final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY")); -275 try { -276 mergeProperty.setString(1, key); -277 mergeProperty.setString(2, value); -278 mergeProperty.executeUpdate(); -279 } finally { -280 DBUtils.closeStatement(mergeProperty); -281 } -282 } catch (MissingResourceException mre) { -283 // No Merge statement, so doing an Update/Insert... -284 PreparedStatement updateProperty = null; -285 PreparedStatement insertProperty = null; -286 try { -287 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); -288 updateProperty.setString(1, value); -289 updateProperty.setString(2, key); -290 if (updateProperty.executeUpdate() == 0) { -291 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); -292 insertProperty.setString(1, key); -293 insertProperty.setString(2, value); -294 insertProperty.executeUpdate(); -295 } +180 /** +181 * Database properties object containing the 'properties' from the database +182 * table. +183 */ +184 private DatabaseProperties databaseProperties; +185 +186 /** +187 * Get the value of databaseProperties. +188 * +189 * @return the value of databaseProperties +190 */ +191 public DatabaseProperties getDatabaseProperties() { +192 return databaseProperties; +193 } +194 +195 /** +196 * Searches the CPE entries in the database and retrieves all entries for a +197 * given vendor and product combination. The returned list will include all +198 * versions of the product that are registered in the NVD CVE data. +199 * +200 * @param vendor the identified vendor name of the dependency being analyzed +201 * @param product the identified name of the product of the dependency being +202 * analyzed +203 * @return a set of vulnerable software +204 */ +205 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { +206 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); +207 ResultSet rs = null; +208 PreparedStatement ps = null; +209 try { +210 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); +211 ps.setString(1, vendor); +212 ps.setString(2, product); +213 rs = ps.executeQuery(); +214 +215 while (rs.next()) { +216 final VulnerableSoftware vs = new VulnerableSoftware(); +217 vs.setCpe(rs.getString(1)); +218 cpe.add(vs); +219 } +220 } catch (SQLException ex) { +221 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +222 LOGGER.debug("", ex); +223 } finally { +224 DBUtils.closeResultSet(rs); +225 DBUtils.closeStatement(ps); +226 } +227 return cpe; +228 } +229 +230 /** +231 * Returns the entire list of vendor/product combinations. +232 * +233 * @return the entire list of vendor/product combinations +234 * @throws DatabaseException thrown when there is an error retrieving the +235 * data from the DB +236 */ +237 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { +238 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); +239 ResultSet rs = null; +240 PreparedStatement ps = null; +241 try { +242 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); +243 rs = ps.executeQuery(); +244 while (rs.next()) { +245 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); +246 } +247 } catch (SQLException ex) { +248 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; +249 throw new DatabaseException(msg, ex); +250 } finally { +251 DBUtils.closeResultSet(rs); +252 DBUtils.closeStatement(ps); +253 } +254 return data; +255 } +256 +257 /** +258 * Returns a set of properties. +259 * +260 * @return the properties from the database +261 */ +262 Properties getProperties() { +263 final Properties prop = new Properties(); +264 PreparedStatement ps = null; +265 ResultSet rs = null; +266 try { +267 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); +268 rs = ps.executeQuery(); +269 while (rs.next()) { +270 prop.setProperty(rs.getString(1), rs.getString(2)); +271 } +272 } catch (SQLException ex) { +273 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +274 LOGGER.debug("", ex); +275 } finally { +276 DBUtils.closeStatement(ps); +277 DBUtils.closeResultSet(rs); +278 } +279 return prop; +280 } +281 +282 /** +283 * Saves a property to the database. +284 * +285 * @param key the property key +286 * @param value the property value +287 */ +288 void saveProperty(String key, String value) { +289 try { +290 try { +291 final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY")); +292 try { +293 mergeProperty.setString(1, key); +294 mergeProperty.setString(2, value); +295 mergeProperty.executeUpdate(); 296 } finally { -297 DBUtils.closeStatement(updateProperty); -298 DBUtils.closeStatement(insertProperty); -299 } -300 } -301 } catch (SQLException ex) { -302 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); -303 LOGGER.debug("", ex); -304 } -305 } -306 -307 /** -308 * Retrieves the vulnerabilities associated with the specified CPE. -309 * -310 * @param cpeStr the CPE name -311 * @return a list of Vulnerabilities -312 * @throws DatabaseException thrown if there is an exception retrieving data -313 */ -314 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { -315 final VulnerableSoftware cpe = new VulnerableSoftware(); -316 try { -317 cpe.parseName(cpeStr); -318 } catch (UnsupportedEncodingException ex) { -319 LOGGER.trace("", ex); -320 } -321 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); -322 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); +297 DBUtils.closeStatement(mergeProperty); +298 } +299 } catch (MissingResourceException mre) { +300 // No Merge statement, so doing an Update/Insert... +301 PreparedStatement updateProperty = null; +302 PreparedStatement insertProperty = null; +303 try { +304 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); +305 updateProperty.setString(1, value); +306 updateProperty.setString(2, key); +307 if (updateProperty.executeUpdate() == 0) { +308 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); +309 insertProperty.setString(1, key); +310 insertProperty.setString(2, value); +311 insertProperty.executeUpdate(); +312 } +313 } finally { +314 DBUtils.closeStatement(updateProperty); +315 DBUtils.closeStatement(insertProperty); +316 } +317 } +318 } catch (SQLException ex) { +319 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); +320 LOGGER.debug("", ex); +321 } +322 } 323 -324 PreparedStatement ps = null; -325 ResultSet rs = null; -326 try { -327 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); -328 ps.setString(1, cpe.getVendor()); -329 ps.setString(2, cpe.getProduct()); -330 rs = ps.executeQuery(); -331 String currentCVE = ""; -332 -333 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); -334 while (rs.next()) { -335 final String cveId = rs.getString(1); -336 if (!currentCVE.equals(cveId)) { //check for match and add -337 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); -338 if (matchedCPE != null) { -339 final Vulnerability v = getVulnerability(currentCVE); -340 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); -341 vulnerabilities.add(v); -342 } -343 vulnSoftware.clear(); -344 currentCVE = cveId; -345 } -346 -347 final String cpeId = rs.getString(2); -348 final String previous = rs.getString(3); -349 final Boolean p = previous != null && !previous.isEmpty(); -350 vulnSoftware.put(cpeId, p); -351 } -352 //remember to process the last set of CVE/CPE entries -353 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); -354 if (matchedCPE != null) { -355 final Vulnerability v = getVulnerability(currentCVE); -356 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); -357 vulnerabilities.add(v); -358 } -359 } catch (SQLException ex) { -360 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); -361 } finally { -362 DBUtils.closeResultSet(rs); -363 DBUtils.closeStatement(ps); -364 } -365 return vulnerabilities; -366 } -367 -368 /** -369 * Gets a vulnerability for the provided CVE. -370 * -371 * @param cve the CVE to lookup -372 * @return a vulnerability object -373 * @throws DatabaseException if an exception occurs -374 */ -375 private Vulnerability getVulnerability(String cve) throws DatabaseException { -376 PreparedStatement psV = null; -377 PreparedStatement psR = null; -378 PreparedStatement psS = null; -379 ResultSet rsV = null; -380 ResultSet rsR = null; -381 ResultSet rsS = null; -382 Vulnerability vuln = null; -383 try { -384 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); -385 psV.setString(1, cve); -386 rsV = psV.executeQuery(); -387 if (rsV.next()) { -388 vuln = new Vulnerability(); -389 vuln.setName(cve); -390 vuln.setDescription(rsV.getString(2)); -391 String cwe = rsV.getString(3); -392 if (cwe != null) { -393 final String name = CweDB.getCweName(cwe); -394 if (name != null) { -395 cwe += ' ' + name; -396 } -397 } -398 final int cveId = rsV.getInt(1); -399 vuln.setCwe(cwe); -400 vuln.setCvssScore(rsV.getFloat(4)); -401 vuln.setCvssAccessVector(rsV.getString(5)); -402 vuln.setCvssAccessComplexity(rsV.getString(6)); -403 vuln.setCvssAuthentication(rsV.getString(7)); -404 vuln.setCvssConfidentialityImpact(rsV.getString(8)); -405 vuln.setCvssIntegrityImpact(rsV.getString(9)); -406 vuln.setCvssAvailabilityImpact(rsV.getString(10)); -407 -408 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); -409 psR.setInt(1, cveId); -410 rsR = psR.executeQuery(); -411 while (rsR.next()) { -412 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); -413 } -414 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); -415 psS.setInt(1, cveId); -416 rsS = psS.executeQuery(); -417 while (rsS.next()) { -418 final String cpe = rsS.getString(1); -419 final String prevVersion = rsS.getString(2); -420 if (prevVersion == null) { -421 vuln.addVulnerableSoftware(cpe); -422 } else { -423 vuln.addVulnerableSoftware(cpe, prevVersion); -424 } -425 } -426 } -427 } catch (SQLException ex) { -428 throw new DatabaseException("Error retrieving " + cve, ex); -429 } finally { -430 DBUtils.closeResultSet(rsV); -431 DBUtils.closeResultSet(rsR); -432 DBUtils.closeResultSet(rsS); -433 DBUtils.closeStatement(psV); -434 DBUtils.closeStatement(psR); -435 DBUtils.closeStatement(psS); -436 } -437 return vuln; -438 } -439 -440 /** -441 * Updates the vulnerability within the database. If the vulnerability does not exist it will be added. -442 * -443 * @param vuln the vulnerability to add to the database -444 * @throws DatabaseException is thrown if the database -445 */ -446 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { -447 PreparedStatement selectVulnerabilityId = null; -448 PreparedStatement deleteVulnerability = null; -449 PreparedStatement deleteReferences = null; -450 PreparedStatement deleteSoftware = null; -451 PreparedStatement updateVulnerability = null; -452 PreparedStatement insertVulnerability = null; -453 PreparedStatement insertReference = null; -454 PreparedStatement selectCpeId = null; -455 PreparedStatement insertCpe = null; -456 PreparedStatement insertSoftware = null; +324 /** +325 * Retrieves the vulnerabilities associated with the specified CPE. +326 * +327 * @param cpeStr the CPE name +328 * @return a list of Vulnerabilities +329 * @throws DatabaseException thrown if there is an exception retrieving data +330 */ +331 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { +332 final VulnerableSoftware cpe = new VulnerableSoftware(); +333 try { +334 cpe.parseName(cpeStr); +335 } catch (UnsupportedEncodingException ex) { +336 LOGGER.trace("", ex); +337 } +338 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); +339 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); +340 +341 PreparedStatement ps = null; +342 ResultSet rs = null; +343 try { +344 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); +345 ps.setString(1, cpe.getVendor()); +346 ps.setString(2, cpe.getProduct()); +347 rs = ps.executeQuery(); +348 String currentCVE = ""; +349 +350 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); +351 while (rs.next()) { +352 final String cveId = rs.getString(1); +353 if (!currentCVE.equals(cveId)) { //check for match and add +354 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +355 if (matchedCPE != null) { +356 final Vulnerability v = getVulnerability(currentCVE); +357 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +358 vulnerabilities.add(v); +359 } +360 vulnSoftware.clear(); +361 currentCVE = cveId; +362 } +363 +364 final String cpeId = rs.getString(2); +365 final String previous = rs.getString(3); +366 final Boolean p = previous != null && !previous.isEmpty(); +367 vulnSoftware.put(cpeId, p); +368 } +369 //remember to process the last set of CVE/CPE entries +370 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +371 if (matchedCPE != null) { +372 final Vulnerability v = getVulnerability(currentCVE); +373 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +374 vulnerabilities.add(v); +375 } +376 } catch (SQLException ex) { +377 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); +378 } finally { +379 DBUtils.closeResultSet(rs); +380 DBUtils.closeStatement(ps); +381 } +382 return vulnerabilities; +383 } +384 +385 /** +386 * Gets a vulnerability for the provided CVE. +387 * +388 * @param cve the CVE to lookup +389 * @return a vulnerability object +390 * @throws DatabaseException if an exception occurs +391 */ +392 public Vulnerability getVulnerability(String cve) throws DatabaseException { +393 PreparedStatement psV = null; +394 PreparedStatement psR = null; +395 PreparedStatement psS = null; +396 ResultSet rsV = null; +397 ResultSet rsR = null; +398 ResultSet rsS = null; +399 Vulnerability vuln = null; +400 +401 try { +402 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); +403 psV.setString(1, cve); +404 rsV = psV.executeQuery(); +405 if (rsV.next()) { +406 vuln = new Vulnerability(); +407 vuln.setName(cve); +408 vuln.setDescription(rsV.getString(2)); +409 String cwe = rsV.getString(3); +410 if (cwe != null) { +411 final String name = CweDB.getCweName(cwe); +412 if (name != null) { +413 cwe += ' ' + name; +414 } +415 } +416 final int cveId = rsV.getInt(1); +417 vuln.setCwe(cwe); +418 vuln.setCvssScore(rsV.getFloat(4)); +419 vuln.setCvssAccessVector(rsV.getString(5)); +420 vuln.setCvssAccessComplexity(rsV.getString(6)); +421 vuln.setCvssAuthentication(rsV.getString(7)); +422 vuln.setCvssConfidentialityImpact(rsV.getString(8)); +423 vuln.setCvssIntegrityImpact(rsV.getString(9)); +424 vuln.setCvssAvailabilityImpact(rsV.getString(10)); +425 +426 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); +427 psR.setInt(1, cveId); +428 rsR = psR.executeQuery(); +429 while (rsR.next()) { +430 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); +431 } +432 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); +433 psS.setInt(1, cveId); +434 rsS = psS.executeQuery(); +435 while (rsS.next()) { +436 final String cpe = rsS.getString(1); +437 final String prevVersion = rsS.getString(2); +438 if (prevVersion == null) { +439 vuln.addVulnerableSoftware(cpe); +440 } else { +441 vuln.addVulnerableSoftware(cpe, prevVersion); +442 } +443 } +444 } +445 } catch (SQLException ex) { +446 throw new DatabaseException("Error retrieving " + cve, ex); +447 } finally { +448 DBUtils.closeResultSet(rsV); +449 DBUtils.closeResultSet(rsR); +450 DBUtils.closeResultSet(rsS); +451 DBUtils.closeStatement(psV); +452 DBUtils.closeStatement(psR); +453 DBUtils.closeStatement(psS); +454 } +455 return vuln; +456 } 457 -458 try { -459 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); -460 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); -461 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); -462 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); -463 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); -464 final String[] ids = {"id"}; -465 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), -466 //Statement.RETURN_GENERATED_KEYS); -467 ids); -468 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); -469 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); -470 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), -471 //Statement.RETURN_GENERATED_KEYS); -472 ids); -473 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); -474 int vulnerabilityId = 0; -475 selectVulnerabilityId.setString(1, vuln.getName()); -476 ResultSet rs = selectVulnerabilityId.executeQuery(); -477 if (rs.next()) { -478 vulnerabilityId = rs.getInt(1); -479 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. -480 deleteReferences.setInt(1, vulnerabilityId); -481 deleteReferences.execute(); -482 deleteSoftware.setInt(1, vulnerabilityId); -483 deleteSoftware.execute(); -484 } -485 DBUtils.closeResultSet(rs); -486 rs = null; -487 if (vulnerabilityId != 0) { -488 if (vuln.getDescription().contains("** REJECT **")) { -489 deleteVulnerability.setInt(1, vulnerabilityId); -490 deleteVulnerability.executeUpdate(); -491 } else { -492 updateVulnerability.setString(1, vuln.getDescription()); -493 updateVulnerability.setString(2, vuln.getCwe()); -494 updateVulnerability.setFloat(3, vuln.getCvssScore()); -495 updateVulnerability.setString(4, vuln.getCvssAccessVector()); -496 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); -497 updateVulnerability.setString(6, vuln.getCvssAuthentication()); -498 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); -499 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); -500 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); -501 updateVulnerability.setInt(10, vulnerabilityId); -502 updateVulnerability.executeUpdate(); -503 } -504 } else { -505 insertVulnerability.setString(1, vuln.getName()); -506 insertVulnerability.setString(2, vuln.getDescription()); -507 insertVulnerability.setString(3, vuln.getCwe()); -508 insertVulnerability.setFloat(4, vuln.getCvssScore()); -509 insertVulnerability.setString(5, vuln.getCvssAccessVector()); -510 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); -511 insertVulnerability.setString(7, vuln.getCvssAuthentication()); -512 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); -513 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); -514 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); -515 insertVulnerability.execute(); -516 try { -517 rs = insertVulnerability.getGeneratedKeys(); -518 rs.next(); -519 vulnerabilityId = rs.getInt(1); -520 } catch (SQLException ex) { -521 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); -522 throw new DatabaseException(msg, ex); -523 } finally { -524 DBUtils.closeResultSet(rs); -525 rs = null; -526 } -527 } -528 insertReference.setInt(1, vulnerabilityId); -529 for (Reference r : vuln.getReferences()) { -530 insertReference.setString(2, r.getName()); -531 insertReference.setString(3, r.getUrl()); -532 insertReference.setString(4, r.getSource()); -533 insertReference.execute(); -534 } -535 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { -536 int cpeProductId = 0; -537 selectCpeId.setString(1, s.getName()); -538 try { -539 rs = selectCpeId.executeQuery(); -540 if (rs.next()) { -541 cpeProductId = rs.getInt(1); -542 } -543 } catch (SQLException ex) { -544 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex); -545 } finally { -546 DBUtils.closeResultSet(rs); -547 rs = null; -548 } -549 -550 if (cpeProductId == 0) { -551 insertCpe.setString(1, s.getName()); -552 insertCpe.setString(2, s.getVendor()); -553 insertCpe.setString(3, s.getProduct()); -554 insertCpe.executeUpdate(); -555 cpeProductId = DBUtils.getGeneratedKey(insertCpe); -556 } -557 if (cpeProductId == 0) { -558 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned"); +458 /** +459 * Updates the vulnerability within the database. If the vulnerability does +460 * not exist it will be added. +461 * +462 * @param vuln the vulnerability to add to the database +463 * @throws DatabaseException is thrown if the database +464 */ +465 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { +466 PreparedStatement selectVulnerabilityId = null; +467 PreparedStatement deleteVulnerability = null; +468 PreparedStatement deleteReferences = null; +469 PreparedStatement deleteSoftware = null; +470 PreparedStatement updateVulnerability = null; +471 PreparedStatement insertVulnerability = null; +472 PreparedStatement insertReference = null; +473 PreparedStatement selectCpeId = null; +474 PreparedStatement insertCpe = null; +475 PreparedStatement insertSoftware = null; +476 +477 try { +478 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); +479 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); +480 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); +481 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); +482 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); +483 final String[] ids = {"id"}; +484 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), +485 //Statement.RETURN_GENERATED_KEYS); +486 ids); +487 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); +488 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); +489 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), +490 //Statement.RETURN_GENERATED_KEYS); +491 ids); +492 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); +493 int vulnerabilityId = 0; +494 selectVulnerabilityId.setString(1, vuln.getName()); +495 ResultSet rs = selectVulnerabilityId.executeQuery(); +496 if (rs.next()) { +497 vulnerabilityId = rs.getInt(1); +498 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. +499 deleteReferences.setInt(1, vulnerabilityId); +500 deleteReferences.execute(); +501 deleteSoftware.setInt(1, vulnerabilityId); +502 deleteSoftware.execute(); +503 } +504 DBUtils.closeResultSet(rs); +505 rs = null; +506 +507 if (vulnerabilityId != 0) { +508 if (vuln.getDescription().contains("** REJECT **")) { +509 deleteVulnerability.setInt(1, vulnerabilityId); +510 deleteVulnerability.executeUpdate(); +511 } else { +512 updateVulnerability.setString(1, vuln.getDescription()); +513 updateVulnerability.setString(2, vuln.getCwe()); +514 updateVulnerability.setFloat(3, vuln.getCvssScore()); +515 updateVulnerability.setString(4, vuln.getCvssAccessVector()); +516 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); +517 updateVulnerability.setString(6, vuln.getCvssAuthentication()); +518 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); +519 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); +520 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); +521 updateVulnerability.setInt(10, vulnerabilityId); +522 updateVulnerability.executeUpdate(); +523 } +524 } else { +525 insertVulnerability.setString(1, vuln.getName()); +526 insertVulnerability.setString(2, vuln.getDescription()); +527 insertVulnerability.setString(3, vuln.getCwe()); +528 insertVulnerability.setFloat(4, vuln.getCvssScore()); +529 insertVulnerability.setString(5, vuln.getCvssAccessVector()); +530 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); +531 insertVulnerability.setString(7, vuln.getCvssAuthentication()); +532 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); +533 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); +534 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); +535 insertVulnerability.execute(); +536 try { +537 rs = insertVulnerability.getGeneratedKeys(); +538 rs.next(); +539 vulnerabilityId = rs.getInt(1); +540 } catch (SQLException ex) { +541 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); +542 throw new DatabaseException(msg, ex); +543 } finally { +544 DBUtils.closeResultSet(rs); +545 rs = null; +546 } +547 } +548 +549 for (Reference r : vuln.getReferences()) { +550 insertReference.setInt(1, vulnerabilityId); +551 insertReference.setString(2, r.getName()); +552 insertReference.setString(3, r.getUrl()); +553 insertReference.setString(4, r.getSource()); +554 +555 if (batchSupported) { +556 insertReference.addBatch(); +557 } else { +558 insertReference.execute(); 559 } -560 -561 insertSoftware.setInt(1, vulnerabilityId); -562 insertSoftware.setInt(2, cpeProductId); -563 if (s.getPreviousVersion() == null) { -564 insertSoftware.setNull(3, java.sql.Types.VARCHAR); -565 } else { -566 insertSoftware.setString(3, s.getPreviousVersion()); -567 } -568 insertSoftware.execute(); -569 } -570 -571 } catch (SQLException ex) { -572 final String msg = String.format("Error updating '%s'", vuln.getName()); -573 LOGGER.debug("", ex); -574 throw new DatabaseException(msg, ex); -575 } finally { -576 DBUtils.closeStatement(selectVulnerabilityId); -577 DBUtils.closeStatement(deleteReferences); -578 DBUtils.closeStatement(deleteSoftware); -579 DBUtils.closeStatement(updateVulnerability); -580 DBUtils.closeStatement(deleteVulnerability); -581 DBUtils.closeStatement(insertVulnerability); -582 DBUtils.closeStatement(insertReference); -583 DBUtils.closeStatement(selectCpeId); -584 DBUtils.closeStatement(insertCpe); -585 DBUtils.closeStatement(insertSoftware); -586 } -587 } -588 -589 /** -590 * Checks to see if data exists so that analysis can be performed. -591 * -592 * @return <code>true</code> if data exists; otherwise <code>false</code> -593 */ -594 public boolean dataExists() { -595 Statement cs = null; -596 ResultSet rs = null; -597 try { -598 cs = conn.createStatement(); -599 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); -600 if (rs.next()) { -601 if (rs.getInt(1) > 0) { -602 return true; -603 } -604 } -605 } catch (SQLException ex) { -606 String dd; -607 try { -608 dd = Settings.getDataDirectory().getAbsolutePath(); -609 } catch (IOException ex1) { -610 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -611 } -612 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. " -613 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please " -614 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " -615 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n", -616 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); -617 LOGGER.debug("", ex); -618 } finally { -619 DBUtils.closeResultSet(rs); -620 DBUtils.closeStatement(cs); -621 } -622 return false; -623 } -624 -625 /** -626 * It is possible that orphaned rows may be generated during database updates. This should be called after all updates have -627 * been completed to ensure orphan entries are removed. -628 */ -629 public void cleanupDatabase() { -630 PreparedStatement ps = null; -631 try { -632 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); -633 if (ps != null) { -634 ps.executeUpdate(); -635 } -636 } catch (SQLException ex) { -637 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -638 LOGGER.debug("", ex); -639 } finally { -640 DBUtils.closeStatement(ps); -641 } -642 } -643 -644 /** -645 * Determines if the given identifiedVersion is affected by the given cpeId and previous version flag. A non-null, non-empty -646 * string passed to the previous version argument indicates that all previous versions are affected. -647 * -648 * @param vendor the vendor of the dependency being analyzed -649 * @param product the product name of the dependency being analyzed -650 * @param vulnerableSoftware a map of the vulnerable software with a boolean indicating if all previous versions are affected -651 * @param identifiedVersion the identified version of the dependency being analyzed -652 * @return true if the identified version is affected, otherwise false -653 */ -654 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, -655 DependencyVersion identifiedVersion) { -656 -657 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); -658 -659 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); -660 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); -661 String majorVersionMatch = null; -662 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -663 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -664 if (v == null || "-".equals(v.toString())) { //all versions -665 return entry; -666 } -667 if (entry.getValue()) { -668 if (matchesAnyPrevious) { -669 return entry; -670 } -671 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { -672 majorVersionMatch = v.getVersionParts().get(0); -673 } -674 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); -675 } -676 } -677 if (matchesAnyPrevious) { -678 return null; -679 } -680 -681 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; -682 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions -683 //then later we process those that affect all versions. This could be done with sorting... -684 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -685 if (!entry.getValue()) { -686 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -687 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -688 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -689 continue; -690 } -691 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -692 //in the above loop or just after loop (if matchesAnyPrevious return null). -693 if (identifiedVersion.equals(v)) { -694 return entry; -695 } -696 } -697 } -698 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -699 if (entry.getValue()) { -700 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -701 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -702 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -703 continue; -704 } -705 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -706 //in the above loop or just after loop (if matchesAnyPrevious return null). -707 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { -708 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { -709 return entry; -710 } -711 } -712 } -713 } -714 return null; -715 } -716 -717 /** -718 * Parses the version (including revision) from a CPE identifier. If no version is identified then a '-' is returned. -719 * -720 * @param cpeStr a cpe identifier -721 * @return a dependency version -722 */ -723 private DependencyVersion parseDependencyVersion(String cpeStr) { -724 final VulnerableSoftware cpe = new VulnerableSoftware(); -725 try { -726 cpe.parseName(cpeStr); -727 } catch (UnsupportedEncodingException ex) { -728 //never going to happen. -729 LOGGER.trace("", ex); -730 } -731 return parseDependencyVersion(cpe); -732 } -733 -734 /** -735 * Takes a CPE and parses out the version number. If no version is identified then a '-' is returned. -736 * -737 * @param cpe a cpe object -738 * @return a dependency version -739 */ -740 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { -741 final DependencyVersion cpeVersion; -742 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { -743 final String versionText; -744 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) { -745 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate()); -746 } else { -747 versionText = cpe.getVersion(); +560 } +561 +562 if (batchSupported) { +563 insertReference.executeBatch(); +564 } +565 +566 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { +567 int cpeProductId = 0; +568 selectCpeId.setString(1, s.getName()); +569 try { +570 rs = selectCpeId.executeQuery(); +571 if (rs.next()) { +572 cpeProductId = rs.getInt(1); +573 } +574 } catch (SQLException ex) { +575 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex); +576 } finally { +577 DBUtils.closeResultSet(rs); +578 rs = null; +579 } +580 +581 if (cpeProductId == 0) { +582 insertCpe.setString(1, s.getName()); +583 insertCpe.setString(2, s.getVendor()); +584 insertCpe.setString(3, s.getProduct()); +585 insertCpe.executeUpdate(); +586 cpeProductId = DBUtils.getGeneratedKey(insertCpe); +587 } +588 if (cpeProductId == 0) { +589 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned"); +590 } +591 +592 insertSoftware.setInt(1, vulnerabilityId); +593 insertSoftware.setInt(2, cpeProductId); +594 +595 if (s.getPreviousVersion() == null) { +596 insertSoftware.setNull(3, java.sql.Types.VARCHAR); +597 } else { +598 insertSoftware.setString(3, s.getPreviousVersion()); +599 } +600 if (batchSupported) { +601 insertSoftware.addBatch(); +602 } else { +603 try { +604 insertSoftware.execute(); +605 } catch (SQLException ex) { +606 if (ex.getMessage().contains("Duplicate entry")) { +607 final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName()); +608 LOGGER.debug(msg, ex); +609 } else { +610 throw ex; +611 } +612 } +613 } +614 } +615 if (batchSupported) { +616 insertSoftware.executeBatch(); +617 } +618 } catch (SQLException ex) { +619 final String msg = String.format("Error updating '%s'", vuln.getName()); +620 LOGGER.debug(msg, ex); +621 throw new DatabaseException(msg, ex); +622 } finally { +623 DBUtils.closeStatement(selectVulnerabilityId); +624 DBUtils.closeStatement(deleteReferences); +625 DBUtils.closeStatement(deleteSoftware); +626 DBUtils.closeStatement(updateVulnerability); +627 DBUtils.closeStatement(deleteVulnerability); +628 DBUtils.closeStatement(insertVulnerability); +629 DBUtils.closeStatement(insertReference); +630 DBUtils.closeStatement(selectCpeId); +631 DBUtils.closeStatement(insertCpe); +632 DBUtils.closeStatement(insertSoftware); +633 } +634 } +635 +636 /** +637 * Checks to see if data exists so that analysis can be performed. +638 * +639 * @return <code>true</code> if data exists; otherwise <code>false</code> +640 */ +641 public boolean dataExists() { +642 Statement cs = null; +643 ResultSet rs = null; +644 try { +645 cs = conn.createStatement(); +646 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); +647 if (rs.next()) { +648 if (rs.getInt(1) > 0) { +649 return true; +650 } +651 } +652 } catch (SQLException ex) { +653 String dd; +654 try { +655 dd = Settings.getDataDirectory().getAbsolutePath(); +656 } catch (IOException ex1) { +657 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +658 } +659 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. " +660 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please " +661 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " +662 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n", +663 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); +664 LOGGER.debug("", ex); +665 } finally { +666 DBUtils.closeResultSet(rs); +667 DBUtils.closeStatement(cs); +668 } +669 return false; +670 } +671 +672 /** +673 * It is possible that orphaned rows may be generated during database +674 * updates. This should be called after all updates have been completed to +675 * ensure orphan entries are removed. +676 */ +677 public void cleanupDatabase() { +678 PreparedStatement ps = null; +679 try { +680 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); +681 if (ps != null) { +682 ps.executeUpdate(); +683 } +684 } catch (SQLException ex) { +685 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +686 LOGGER.debug("", ex); +687 } finally { +688 DBUtils.closeStatement(ps); +689 } +690 } +691 +692 /** +693 * Determines if the given identifiedVersion is affected by the given cpeId +694 * and previous version flag. A non-null, non-empty string passed to the +695 * previous version argument indicates that all previous versions are +696 * affected. +697 * +698 * @param vendor the vendor of the dependency being analyzed +699 * @param product the product name of the dependency being analyzed +700 * @param vulnerableSoftware a map of the vulnerable software with a boolean +701 * indicating if all previous versions are affected +702 * @param identifiedVersion the identified version of the dependency being +703 * analyzed +704 * @return true if the identified version is affected, otherwise false +705 */ +706 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, +707 DependencyVersion identifiedVersion) { +708 +709 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); +710 +711 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); +712 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); +713 String majorVersionMatch = null; +714 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +715 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +716 if (v == null || "-".equals(v.toString())) { //all versions +717 return entry; +718 } +719 if (entry.getValue()) { +720 if (matchesAnyPrevious) { +721 return entry; +722 } +723 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { +724 majorVersionMatch = v.getVersionParts().get(0); +725 } +726 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); +727 } +728 } +729 if (matchesAnyPrevious) { +730 return null; +731 } +732 +733 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; +734 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions +735 //then later we process those that affect all versions. This could be done with sorting... +736 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +737 if (!entry.getValue()) { +738 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +739 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +740 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +741 continue; +742 } +743 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +744 //in the above loop or just after loop (if matchesAnyPrevious return null). +745 if (identifiedVersion.equals(v)) { +746 return entry; +747 } 748 } -749 cpeVersion = DependencyVersionUtil.parseVersion(versionText); -750 } else { -751 cpeVersion = new DependencyVersion("-"); -752 } -753 return cpeVersion; -754 } -755 -756 /** -757 * This method is only referenced in unused code. -758 * -759 * Deletes unused dictionary entries from the database. -760 */ -761 public void deleteUnusedCpe() { -762 CallableStatement cs = null; -763 try { -764 cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); -765 cs.executeUpdate(); -766 } catch (SQLException ex) { -767 LOGGER.error("Unable to delete CPE dictionary entries", ex); -768 } finally { -769 DBUtils.closeStatement(cs); -770 } -771 } -772 -773 /** -774 * This method is only referenced in unused code and will likely break on MySQL if ever used due to the MERGE statement. -775 * -776 * Merges CPE entries into the database. -777 * -778 * @param cpe the CPE identifier -779 * @param vendor the CPE vendor -780 * @param product the CPE product -781 */ -782 public void addCpe(String cpe, String vendor, String product) { -783 PreparedStatement ps = null; -784 try { -785 ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE")); -786 ps.setString(1, cpe); -787 ps.setString(2, vendor); -788 ps.setString(3, product); -789 ps.executeUpdate(); -790 } catch (SQLException ex) { -791 LOGGER.error("Unable to add CPE dictionary entry", ex); -792 } finally { -793 DBUtils.closeStatement(ps); -794 } -795 } -796 } +749 } +750 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +751 if (entry.getValue()) { +752 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +753 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +754 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +755 continue; +756 } +757 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +758 //in the above loop or just after loop (if matchesAnyPrevious return null). +759 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { +760 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { +761 return entry; +762 } +763 } +764 } +765 } +766 return null; +767 } +768 +769 /** +770 * Parses the version (including revision) from a CPE identifier. If no +771 * version is identified then a '-' is returned. +772 * +773 * @param cpeStr a cpe identifier +774 * @return a dependency version +775 */ +776 private DependencyVersion parseDependencyVersion(String cpeStr) { +777 final VulnerableSoftware cpe = new VulnerableSoftware(); +778 try { +779 cpe.parseName(cpeStr); +780 } catch (UnsupportedEncodingException ex) { +781 //never going to happen. +782 LOGGER.trace("", ex); +783 } +784 return parseDependencyVersion(cpe); +785 } +786 +787 /** +788 * Takes a CPE and parses out the version number. If no version is +789 * identified then a '-' is returned. +790 * +791 * @param cpe a cpe object +792 * @return a dependency version +793 */ +794 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { +795 final DependencyVersion cpeVersion; +796 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { +797 final String versionText; +798 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) { +799 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate()); +800 } else { +801 versionText = cpe.getVersion(); +802 } +803 cpeVersion = DependencyVersionUtil.parseVersion(versionText); +804 } else { +805 cpeVersion = new DependencyVersion("-"); +806 } +807 return cpeVersion; +808 } +809 +810 /** +811 * This method is only referenced in unused code. +812 * +813 * Deletes unused dictionary entries from the database. +814 */ +815 public void deleteUnusedCpe() { +816 CallableStatement cs = null; +817 try { +818 cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); +819 cs.executeUpdate(); +820 } catch (SQLException ex) { +821 LOGGER.error("Unable to delete CPE dictionary entries", ex); +822 } finally { +823 DBUtils.closeStatement(cs); +824 } +825 } +826 +827 /** +828 * This method is only referenced in unused code and will likely break on +829 * MySQL if ever used due to the MERGE statement. +830 * +831 * Merges CPE entries into the database. +832 * +833 * @param cpe the CPE identifier +834 * @param vendor the CPE vendor +835 * @param product the CPE product +836 */ +837 public void addCpe(String cpe, String vendor, String product) { +838 PreparedStatement ps = null; +839 try { +840 ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE")); +841 ps.setString(1, cpe); +842 ps.setString(2, vendor); +843 ps.setString(3, product); +844 ps.executeUpdate(); +845 } catch (SQLException ex) { +846 LOGGER.error("Unable to add CPE dictionary entry", ex); +847 } finally { +848 DBUtils.closeStatement(ps); +849 } +850 } +851 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html index ea1166c2e..af0294bde 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html index 5715cadbf..a155a3353 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html index dadf93bf7..8d5a2bef0 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html @@ -68,287 +68,300 @@ 60 61 /** 62 * <p> -63 * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.</p> -64 * -65 * @throws UpdateException is thrown if there is an error updating the database -66 */ -67 @Override -68 public void update() throws UpdateException { -69 try { -70 openDataStores(); -71 boolean autoUpdate = true; -72 try { -73 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -74 } catch (InvalidSettingException ex) { -75 LOGGER.debug("Invalid setting for auto-update; using true."); -76 } -77 if (autoUpdate && checkUpdate()) { -78 final UpdateableNvdCve updateable = getUpdatesNeeded(); -79 if (updateable.isUpdateNeeded()) { -80 performUpdate(updateable); -81 } -82 } -83 } catch (MalformedURLException ex) { -84 LOGGER.warn( -85 "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data."); -86 LOGGER.debug("", ex); -87 } catch (DownloadFailedException ex) { -88 LOGGER.warn( -89 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); -90 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { -91 LOGGER.info( -92 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); -93 } -94 LOGGER.debug("", ex); -95 } finally { -96 closeDataStores(); -97 } -98 } -99 -100 /** -101 * Checks if the NVD CVE XML files were last checked recently. As an optimization, we can avoid repetitive checks against the -102 * NVD. Setting CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before checking again. A database property -103 * stores the timestamp of the last check. -104 * -105 * @return true to proceed with the check, or false to skip. -106 * @throws UpdateException thrown when there is an issue checking for updates. -107 */ -108 private boolean checkUpdate() throws UpdateException { -109 boolean proceed = true; -110 // If the valid setting has not been specified, then we proceed to check... -111 final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0); -112 if (dataExists() && 0 < validForHours) { -113 // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec -114 final long msValid = validForHours * 60L * 60L * 1000L; -115 final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0")); -116 final long now = System.currentTimeMillis(); -117 proceed = (now - lastChecked) > msValid; -118 if (proceed) { -119 getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(now)); -120 } else { -121 LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours); -122 LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.", -123 lastChecked, now, msValid); -124 } -125 } -126 return proceed; -127 } -128 -129 /** -130 * Checks the CVE Index to ensure data exists and analysis can continue. -131 * -132 * @return true if the database contains data -133 */ -134 private boolean dataExists() { -135 CveDB cve = null; -136 try { -137 cve = new CveDB(); -138 cve.open(); -139 return cve.dataExists(); -140 } catch (DatabaseException ex) { -141 return false; -142 } finally { -143 if (cve != null) { -144 cve.close(); -145 } -146 } -147 } -148 -149 /** -150 * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database. -151 * -152 * @param updateable a collection of NVD CVE data file references that need to be downloaded and processed to update the -153 * database -154 * @throws UpdateException is thrown if there is an error updating the database -155 */ -156 public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { -157 int maxUpdates = 0; -158 try { -159 for (NvdCveInfo cve : updateable) { -160 if (cve.getNeedsUpdate()) { -161 maxUpdates += 1; -162 } -163 } -164 if (maxUpdates <= 0) { -165 return; -166 } -167 if (maxUpdates > 3) { -168 LOGGER.info( -169 "NVD CVE requires several updates; this could take a couple of minutes."); -170 } -171 if (maxUpdates > 0) { -172 openDataStores(); -173 } -174 -175 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; -176 -177 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); -178 final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); -179 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates); -180 for (NvdCveInfo cve : updateable) { -181 if (cve.getNeedsUpdate()) { -182 final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance()); -183 downloadFutures.add(downloadExecutors.submit(call)); -184 } -185 } -186 downloadExecutors.shutdown(); -187 -188 //next, move the future future processTasks to just future processTasks -189 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates); -190 for (Future<Future<ProcessTask>> future : downloadFutures) { -191 Future<ProcessTask> task = null; -192 try { -193 task = future.get(); -194 } catch (InterruptedException ex) { -195 downloadExecutors.shutdownNow(); -196 processExecutor.shutdownNow(); -197 -198 LOGGER.debug("Thread was interrupted during download", ex); -199 throw new UpdateException("The download was interrupted", ex); -200 } catch (ExecutionException ex) { +63 * Downloads the latest NVD CVE XML file from the web and imports it into +64 * the current CVE Database.</p> +65 * +66 * @throws UpdateException is thrown if there is an error updating the +67 * database +68 */ +69 @Override +70 public void update() throws UpdateException { +71 try { +72 openDataStores(); +73 boolean autoUpdate = true; +74 try { +75 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +76 } catch (InvalidSettingException ex) { +77 LOGGER.debug("Invalid setting for auto-update; using true."); +78 } +79 if (autoUpdate && checkUpdate()) { +80 final UpdateableNvdCve updateable = getUpdatesNeeded(); +81 getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); +82 if (updateable.isUpdateNeeded()) { +83 performUpdate(updateable); +84 } +85 } +86 } catch (MalformedURLException ex) { +87 LOGGER.warn( +88 "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data."); +89 LOGGER.debug("", ex); +90 } catch (DownloadFailedException ex) { +91 LOGGER.warn( +92 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); +93 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { +94 LOGGER.info( +95 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); +96 } +97 LOGGER.debug("", ex); +98 } finally { +99 closeDataStores(); +100 } +101 } +102 +103 /** +104 * Checks if the NVD CVE XML files were last checked recently. As an +105 * optimization, we can avoid repetitive checks against the NVD. Setting +106 * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before +107 * checking again. A database property stores the timestamp of the last +108 * check. +109 * +110 * @return true to proceed with the check, or false to skip. +111 * @throws UpdateException thrown when there is an issue checking for +112 * updates. +113 */ +114 private boolean checkUpdate() throws UpdateException { +115 boolean proceed = true; +116 // If the valid setting has not been specified, then we proceed to check... +117 final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0); +118 if (dataExists() && 0 < validForHours) { +119 // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec +120 final long msValid = validForHours * 60L * 60L * 1000L; +121 final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0")); +122 final long now = System.currentTimeMillis(); +123 proceed = (now - lastChecked) > msValid; +124 if (!proceed) { +125 LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours); +126 LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.", +127 lastChecked, now, msValid); +128 } +129 } +130 return proceed; +131 } +132 +133 /** +134 * Checks the CVE Index to ensure data exists and analysis can continue. +135 * +136 * @return true if the database contains data +137 */ +138 private boolean dataExists() { +139 CveDB cve = null; +140 try { +141 cve = new CveDB(); +142 cve.open(); +143 return cve.dataExists(); +144 } catch (DatabaseException ex) { +145 return false; +146 } finally { +147 if (cve != null) { +148 cve.close(); +149 } +150 } +151 } +152 +153 /** +154 * Downloads the latest NVD CVE XML file from the web and imports it into +155 * the current CVE Database. +156 * +157 * @param updateable a collection of NVD CVE data file references that need +158 * to be downloaded and processed to update the database +159 * @throws UpdateException is thrown if there is an error updating the +160 * database +161 */ +162 public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { +163 int maxUpdates = 0; +164 try { +165 for (NvdCveInfo cve : updateable) { +166 if (cve.getNeedsUpdate()) { +167 maxUpdates += 1; +168 } +169 } +170 if (maxUpdates <= 0) { +171 return; +172 } +173 if (maxUpdates > 3) { +174 LOGGER.info( +175 "NVD CVE requires several updates; this could take a couple of minutes."); +176 } +177 if (maxUpdates > 0) { +178 openDataStores(); +179 } +180 +181 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; +182 +183 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); +184 final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); +185 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates); +186 for (NvdCveInfo cve : updateable) { +187 if (cve.getNeedsUpdate()) { +188 final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance()); +189 downloadFutures.add(downloadExecutors.submit(call)); +190 } +191 } +192 downloadExecutors.shutdown(); +193 +194 //next, move the future future processTasks to just future processTasks +195 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates); +196 for (Future<Future<ProcessTask>> future : downloadFutures) { +197 Future<ProcessTask> task = null; +198 try { +199 task = future.get(); +200 } catch (InterruptedException ex) { 201 downloadExecutors.shutdownNow(); 202 processExecutor.shutdownNow(); 203 -204 LOGGER.debug("Thread was interrupted during download execution", ex); -205 throw new UpdateException("The execution of the download was interrupted", ex); -206 } -207 if (task == null) { -208 downloadExecutors.shutdownNow(); -209 processExecutor.shutdownNow(); -210 LOGGER.debug("Thread was interrupted during download"); -211 throw new UpdateException("The download was interrupted; unable to complete the update"); -212 } else { -213 processFutures.add(task); -214 } -215 } -216 -217 for (Future<ProcessTask> future : processFutures) { -218 try { -219 final ProcessTask task = future.get(); -220 if (task.getException() != null) { -221 throw task.getException(); -222 } -223 } catch (InterruptedException ex) { -224 processExecutor.shutdownNow(); -225 LOGGER.debug("Thread was interrupted during processing", ex); -226 throw new UpdateException(ex); -227 } catch (ExecutionException ex) { -228 processExecutor.shutdownNow(); -229 LOGGER.debug("Execution Exception during process", ex); -230 throw new UpdateException(ex); -231 } finally { -232 processExecutor.shutdown(); -233 } -234 } -235 -236 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it) -237 getProperties().save(updateable.get(MODIFIED)); -238 LOGGER.info("Begin database maintenance."); -239 getCveDB().cleanupDatabase(); -240 LOGGER.info("End database maintenance."); -241 } -242 } finally { -243 closeDataStores(); -244 } -245 } -246 -247 /** -248 * Determines if the index needs to be updated. This is done by fetching the NVD CVE meta data and checking the last update -249 * date. If the data needs to be refreshed this method will return the NvdCveUrl for the files that need to be updated. -250 * -251 * @return the collection of files that need to be updated -252 * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta data is incorrect -253 * @throws DownloadFailedException is thrown if there is an error. downloading the NVD CVE download data file -254 * @throws UpdateException Is thrown if there is an issue with the last updated properties file -255 */ -256 protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { -257 UpdateableNvdCve updates = null; -258 try { -259 updates = retrieveCurrentTimestampsFromWeb(); -260 } catch (InvalidDataException ex) { -261 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page"; -262 LOGGER.debug(msg, ex); -263 throw new DownloadFailedException(msg, ex); -264 } catch (InvalidSettingException ex) { -265 LOGGER.debug("Invalid setting found when retrieving timestamps", ex); -266 throw new DownloadFailedException("Invalid settings", ex); -267 } -268 -269 if (updates == null) { -270 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data"); -271 } -272 if (!getProperties().isEmpty()) { -273 try { -274 final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0")); -275 final long now = System.currentTimeMillis(); -276 final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7); -277 if (lastUpdated == updates.getTimeStamp(MODIFIED)) { -278 updates.clear(); //we don't need to update anything. -279 } else if (DateUtil.withinDateRange(lastUpdated, now, days)) { -280 for (NvdCveInfo entry : updates) { -281 if (MODIFIED.equals(entry.getId())) { -282 entry.setNeedsUpdate(true); -283 } else { -284 entry.setNeedsUpdate(false); -285 } -286 } -287 } else { //we figure out which of the several XML files need to be downloaded. -288 for (NvdCveInfo entry : updates) { -289 if (MODIFIED.equals(entry.getId())) { -290 entry.setNeedsUpdate(true); -291 } else { -292 long currentTimestamp = 0; -293 try { -294 currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE -295 + entry.getId(), "0")); -296 } catch (NumberFormatException ex) { -297 LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated", -298 DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex); -299 } -300 if (currentTimestamp == entry.getTimestamp()) { -301 entry.setNeedsUpdate(false); -302 } -303 } -304 } -305 } -306 } catch (NumberFormatException ex) { -307 LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); -308 LOGGER.debug("", ex); -309 } -310 } -311 return updates; -312 } -313 -314 /** -315 * Retrieves the timestamps from the NVD CVE meta data file. -316 * -317 * @return the timestamp from the currently published nvdcve downloads page -318 * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data is incorrect. -319 * @throws DownloadFailedException thrown if there is an error downloading the nvd cve meta data file -320 * @throws InvalidDataException thrown if there is an exception parsing the timestamps -321 * @throws InvalidSettingException thrown if the settings are invalid -322 */ -323 private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() -324 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException { -325 -326 final UpdateableNvdCve updates = new UpdateableNvdCve(); -327 updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL), -328 Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL), -329 false); -330 -331 final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR); -332 final int end = Calendar.getInstance().get(Calendar.YEAR); -333 final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0); -334 final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2); -335 for (int i = start; i <= end; i++) { -336 updates.add(Integer.toString(i), String.format(baseUrl20, i), -337 String.format(baseUrl12, i), -338 true); -339 } -340 return updates; -341 } -342 -343 } +204 LOGGER.debug("Thread was interrupted during download", ex); +205 throw new UpdateException("The download was interrupted", ex); +206 } catch (ExecutionException ex) { +207 downloadExecutors.shutdownNow(); +208 processExecutor.shutdownNow(); +209 +210 LOGGER.debug("Thread was interrupted during download execution", ex); +211 throw new UpdateException("The execution of the download was interrupted", ex); +212 } +213 if (task == null) { +214 downloadExecutors.shutdownNow(); +215 processExecutor.shutdownNow(); +216 LOGGER.debug("Thread was interrupted during download"); +217 throw new UpdateException("The download was interrupted; unable to complete the update"); +218 } else { +219 processFutures.add(task); +220 } +221 } +222 +223 for (Future<ProcessTask> future : processFutures) { +224 try { +225 final ProcessTask task = future.get(); +226 if (task.getException() != null) { +227 throw task.getException(); +228 } +229 } catch (InterruptedException ex) { +230 processExecutor.shutdownNow(); +231 LOGGER.debug("Thread was interrupted during processing", ex); +232 throw new UpdateException(ex); +233 } catch (ExecutionException ex) { +234 processExecutor.shutdownNow(); +235 LOGGER.debug("Execution Exception during process", ex); +236 throw new UpdateException(ex); +237 } finally { +238 processExecutor.shutdown(); +239 } +240 } +241 +242 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it) +243 getProperties().save(updateable.get(MODIFIED)); +244 LOGGER.info("Begin database maintenance."); +245 getCveDB().cleanupDatabase(); +246 LOGGER.info("End database maintenance."); +247 } +248 } finally { +249 closeDataStores(); +250 } +251 } +252 +253 /** +254 * Determines if the index needs to be updated. This is done by fetching the +255 * NVD CVE meta data and checking the last update date. If the data needs to +256 * be refreshed this method will return the NvdCveUrl for the files that +257 * need to be updated. +258 * +259 * @return the collection of files that need to be updated +260 * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta +261 * data is incorrect +262 * @throws DownloadFailedException is thrown if there is an error. +263 * downloading the NVD CVE download data file +264 * @throws UpdateException Is thrown if there is an issue with the last +265 * updated properties file +266 */ +267 protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { +268 UpdateableNvdCve updates = null; +269 try { +270 updates = retrieveCurrentTimestampsFromWeb(); +271 } catch (InvalidDataException ex) { +272 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page"; +273 LOGGER.debug(msg, ex); +274 throw new DownloadFailedException(msg, ex); +275 } catch (InvalidSettingException ex) { +276 LOGGER.debug("Invalid setting found when retrieving timestamps", ex); +277 throw new DownloadFailedException("Invalid settings", ex); +278 } +279 +280 if (updates == null) { +281 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data"); +282 } +283 if (!getProperties().isEmpty()) { +284 try { +285 final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0")); +286 final long now = System.currentTimeMillis(); +287 final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7); +288 if (lastUpdated == updates.getTimeStamp(MODIFIED)) { +289 updates.clear(); //we don't need to update anything. +290 } else if (DateUtil.withinDateRange(lastUpdated, now, days)) { +291 for (NvdCveInfo entry : updates) { +292 if (MODIFIED.equals(entry.getId())) { +293 entry.setNeedsUpdate(true); +294 } else { +295 entry.setNeedsUpdate(false); +296 } +297 } +298 } else { //we figure out which of the several XML files need to be downloaded. +299 for (NvdCveInfo entry : updates) { +300 if (MODIFIED.equals(entry.getId())) { +301 entry.setNeedsUpdate(true); +302 } else { +303 long currentTimestamp = 0; +304 try { +305 currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE +306 + entry.getId(), "0")); +307 } catch (NumberFormatException ex) { +308 LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated", +309 DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex); +310 } +311 if (currentTimestamp == entry.getTimestamp()) { +312 entry.setNeedsUpdate(false); +313 } +314 } +315 } +316 } +317 } catch (NumberFormatException ex) { +318 LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); +319 LOGGER.debug("", ex); +320 } +321 } +322 return updates; +323 } +324 +325 /** +326 * Retrieves the timestamps from the NVD CVE meta data file. +327 * +328 * @return the timestamp from the currently published nvdcve downloads page +329 * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data +330 * is incorrect. +331 * @throws DownloadFailedException thrown if there is an error downloading +332 * the nvd cve meta data file +333 * @throws InvalidDataException thrown if there is an exception parsing the +334 * timestamps +335 * @throws InvalidSettingException thrown if the settings are invalid +336 */ +337 private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() +338 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException { +339 +340 final UpdateableNvdCve updates = new UpdateableNvdCve(); +341 updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL), +342 Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL), +343 false); +344 +345 final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR); +346 final int end = Calendar.getInstance().get(Calendar.YEAR); +347 final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0); +348 final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2); +349 for (int i = start; i <= end; i++) { +350 updates.add(Integer.toString(i), String.format(baseUrl20, i), +351 String.format(baseUrl12, i), +352 true); +353 } +354 return updates; +355 } +356 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html index dac667f69..1f34a5f94 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update.cpe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.cpe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html index bbe44ce89..44c6d63ac 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update.cpe + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.cpe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html index 61290944a..dde687c2a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html index 12ccbae68..c12f2cda7 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html index 7f1630099..480cf5e9e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html @@ -269,62 +269,63 @@ 261 try { 262 is.close(); 263 } catch (IOException ex) { -264 } -265 } -266 } -267 } -268 -269 /** -270 * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified. -271 * -272 * @param file the archive file -273 * @throws FileNotFoundException thrown if the file does not exist -274 * @throws IOException thrown if there is an error extracting the file. -275 */ -276 private void extractGzip(File file) throws FileNotFoundException, IOException { -277 final String originalPath = file.getPath(); -278 final File gzip = new File(originalPath + ".gz"); -279 if (gzip.isFile() && !gzip.delete()) { -280 gzip.deleteOnExit(); -281 } -282 if (!file.renameTo(gzip)) { -283 throw new IOException("Unable to rename '" + file.getPath() + "'"); -284 } -285 final File newfile = new File(originalPath); -286 -287 final byte[] buffer = new byte[4096]; -288 -289 GZIPInputStream cin = null; -290 FileOutputStream out = null; -291 try { -292 cin = new GZIPInputStream(new FileInputStream(gzip)); -293 out = new FileOutputStream(newfile); -294 -295 int len; -296 while ((len = cin.read(buffer)) > 0) { -297 out.write(buffer, 0, len); -298 } -299 } finally { -300 if (cin != null) { -301 try { -302 cin.close(); -303 } catch (IOException ex) { -304 LOGGER.trace("ignore", ex); -305 } -306 } -307 if (out != null) { -308 try { -309 out.close(); -310 } catch (IOException ex) { -311 LOGGER.trace("ignore", ex); -312 } -313 } -314 if (gzip.isFile()) { -315 FileUtils.deleteQuietly(gzip); -316 } -317 } -318 } -319 } +264 LOGGER.debug("Error closing stream", ex); +265 } +266 } +267 } +268 } +269 +270 /** +271 * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified. +272 * +273 * @param file the archive file +274 * @throws FileNotFoundException thrown if the file does not exist +275 * @throws IOException thrown if there is an error extracting the file. +276 */ +277 private void extractGzip(File file) throws FileNotFoundException, IOException { +278 final String originalPath = file.getPath(); +279 final File gzip = new File(originalPath + ".gz"); +280 if (gzip.isFile() && !gzip.delete()) { +281 gzip.deleteOnExit(); +282 } +283 if (!file.renameTo(gzip)) { +284 throw new IOException("Unable to rename '" + file.getPath() + "'"); +285 } +286 final File newfile = new File(originalPath); +287 +288 final byte[] buffer = new byte[4096]; +289 +290 GZIPInputStream cin = null; +291 FileOutputStream out = null; +292 try { +293 cin = new GZIPInputStream(new FileInputStream(gzip)); +294 out = new FileOutputStream(newfile); +295 +296 int len; +297 while ((len = cin.read(buffer)) > 0) { +298 out.write(buffer, 0, len); +299 } +300 } finally { +301 if (cin != null) { +302 try { +303 cin.close(); +304 } catch (IOException ex) { +305 LOGGER.trace("ignore", ex); +306 } +307 } +308 if (out != null) { +309 try { +310 out.close(); +311 } catch (IOException ex) { +312 LOGGER.trace("ignore", ex); +313 } +314 } +315 if (gzip.isFile()) { +316 FileUtils.deleteQuietly(gzip); +317 } +318 } +319 } +320 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html index f84de6677..6cd7a2b99 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html @@ -262,245 +262,244 @@ 254 * @throws IOException thrown if there is an IOException with the CPE Index 255 */ 256 private void saveEntry(Vulnerability vuln) throws DatabaseException, CorruptIndexException, IOException { -257 if (cveDB == null) { -258 return; -259 } -260 final String cveName = vuln.getName(); -261 if (prevVersionVulnMap.containsKey(cveName)) { -262 final List<VulnerableSoftware> vulnSoftware = prevVersionVulnMap.get(cveName); -263 for (VulnerableSoftware vs : vulnSoftware) { -264 vuln.updateVulnerableSoftware(vs); -265 } +257 final String cveName = vuln.getName(); +258 if (prevVersionVulnMap != null && prevVersionVulnMap.containsKey(cveName)) { +259 final List<VulnerableSoftware> vulnSoftware = prevVersionVulnMap.get(cveName); +260 for (VulnerableSoftware vs : vulnSoftware) { +261 vuln.updateVulnerableSoftware(vs); +262 } +263 } +264 if (cveDB != null) { +265 cveDB.updateVulnerability(vuln); 266 } -267 cveDB.updateVulnerability(vuln); -268 } -269 -270 // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node"> -271 /** -272 * A simple class to maintain information about the current element while parsing the NVD CVE XML. -273 */ -274 protected static class Element { -275 -276 /** -277 * A node type in the NVD CVE Schema 2.0 -278 */ -279 public static final String NVD = "nvd"; -280 /** -281 * A node type in the NVD CVE Schema 2.0 -282 */ -283 public static final String ENTRY = "entry"; -284 /** -285 * A node type in the NVD CVE Schema 2.0 -286 */ -287 public static final String VULN_PRODUCT = "vuln:product"; -288 /** -289 * A node type in the NVD CVE Schema 2.0 -290 */ -291 public static final String VULN_REFERENCES = "vuln:references"; -292 /** -293 * A node type in the NVD CVE Schema 2.0 -294 */ -295 public static final String VULN_SOURCE = "vuln:source"; -296 /** -297 * A node type in the NVD CVE Schema 2.0 -298 */ -299 public static final String VULN_REFERENCE = "vuln:reference"; -300 /** -301 * A node type in the NVD CVE Schema 2.0 -302 */ -303 public static final String VULN_SUMMARY = "vuln:summary"; -304 /** -305 * A node type in the NVD CVE Schema 2.0 -306 */ -307 public static final String VULN_CWE = "vuln:cwe"; -308 /** -309 * A node type in the NVD CVE Schema 2.0 -310 */ -311 public static final String CVSS_SCORE = "cvss:score"; -312 /** -313 * A node type in the NVD CVE Schema 2.0 -314 */ -315 public static final String CVSS_ACCESS_VECTOR = "cvss:access-vector"; -316 /** -317 * A node type in the NVD CVE Schema 2.0 -318 */ -319 public static final String CVSS_ACCESS_COMPLEXITY = "cvss:access-complexity"; -320 /** -321 * A node type in the NVD CVE Schema 2.0 -322 */ -323 public static final String CVSS_AUTHENTICATION = "cvss:authentication"; -324 /** -325 * A node type in the NVD CVE Schema 2.0 -326 */ -327 public static final String CVSS_CONFIDENTIALITY_IMPACT = "cvss:confidentiality-impact"; -328 /** -329 * A node type in the NVD CVE Schema 2.0 -330 */ -331 public static final String CVSS_INTEGRITY_IMPACT = "cvss:integrity-impact"; -332 /** -333 * A node type in the NVD CVE Schema 2.0 -334 */ -335 public static final String CVSS_AVAILABILITY_IMPACT = "cvss:availability-impact"; -336 /** -337 * The current node. -338 */ -339 private String node; -340 -341 /** -342 * Gets the value of node. -343 * -344 * @return the value of node -345 */ -346 public String getNode() { -347 return this.node; -348 } -349 -350 /** -351 * Sets the value of node. -352 * -353 * @param node new value of node -354 */ -355 public void setNode(String node) { -356 this.node = node; -357 } -358 -359 /** -360 * Checks if the handler is at the NVD node. -361 * -362 * @return true or false -363 */ -364 public boolean isNVDNode() { -365 return NVD.equals(node); -366 } -367 -368 /** -369 * Checks if the handler is at the ENTRY node. -370 * -371 * @return true or false -372 */ -373 public boolean isEntryNode() { -374 return ENTRY.equals(node); -375 } -376 -377 /** -378 * Checks if the handler is at the VULN_PRODUCT node. -379 * -380 * @return true or false -381 */ -382 public boolean isVulnProductNode() { -383 return VULN_PRODUCT.equals(node); -384 } -385 -386 /** -387 * Checks if the handler is at the REFERENCES node. -388 * -389 * @return true or false -390 */ -391 public boolean isVulnReferencesNode() { -392 return VULN_REFERENCES.equals(node); -393 } -394 -395 /** -396 * Checks if the handler is at the REFERENCE node. -397 * -398 * @return true or false -399 */ -400 public boolean isVulnReferenceNode() { -401 return VULN_REFERENCE.equals(node); -402 } -403 -404 /** -405 * Checks if the handler is at the VULN_SOURCE node. -406 * -407 * @return true or false -408 */ -409 public boolean isVulnSourceNode() { -410 return VULN_SOURCE.equals(node); -411 } -412 -413 /** -414 * Checks if the handler is at the VULN_SUMMARY node. -415 * -416 * @return true or false -417 */ -418 public boolean isVulnSummaryNode() { -419 return VULN_SUMMARY.equals(node); -420 } -421 -422 /** -423 * Checks if the handler is at the VULN_CWE node. -424 * -425 * @return true or false -426 */ -427 public boolean isVulnCWENode() { -428 return VULN_CWE.equals(node); -429 } -430 -431 /** -432 * Checks if the handler is at the CVSS_SCORE node. -433 * -434 * @return true or false -435 */ -436 public boolean isCVSSScoreNode() { -437 return CVSS_SCORE.equals(node); -438 } -439 -440 /** -441 * Checks if the handler is at the CVSS_ACCESS_VECTOR node. -442 * -443 * @return true or false -444 */ -445 public boolean isCVSSAccessVectorNode() { -446 return CVSS_ACCESS_VECTOR.equals(node); -447 } -448 -449 /** -450 * Checks if the handler is at the CVSS_ACCESS_COMPLEXITY node. -451 * -452 * @return true or false -453 */ -454 public boolean isCVSSAccessComplexityNode() { -455 return CVSS_ACCESS_COMPLEXITY.equals(node); -456 } -457 -458 /** -459 * Checks if the handler is at the CVSS_AUTHENTICATION node. -460 * -461 * @return true or false -462 */ -463 public boolean isCVSSAuthenticationNode() { -464 return CVSS_AUTHENTICATION.equals(node); -465 } -466 -467 /** -468 * Checks if the handler is at the CVSS_CONFIDENTIALITY_IMPACT node. -469 * -470 * @return true or false -471 */ -472 public boolean isCVSSConfidentialityImpactNode() { -473 return CVSS_CONFIDENTIALITY_IMPACT.equals(node); -474 } -475 -476 /** -477 * Checks if the handler is at the CVSS_INTEGRITY_IMPACT node. -478 * -479 * @return true or false -480 */ -481 public boolean isCVSSIntegrityImpactNode() { -482 return CVSS_INTEGRITY_IMPACT.equals(node); -483 } -484 -485 /** -486 * Checks if the handler is at the CVSS_AVAILABILITY_IMPACT node. -487 * -488 * @return true or false -489 */ -490 public boolean isCVSSAvailabilityImpactNode() { -491 return CVSS_AVAILABILITY_IMPACT.equals(node); -492 } -493 } -494 // </editor-fold> -495 } +267 } +268 +269 // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node"> +270 /** +271 * A simple class to maintain information about the current element while parsing the NVD CVE XML. +272 */ +273 protected static class Element { +274 +275 /** +276 * A node type in the NVD CVE Schema 2.0 +277 */ +278 public static final String NVD = "nvd"; +279 /** +280 * A node type in the NVD CVE Schema 2.0 +281 */ +282 public static final String ENTRY = "entry"; +283 /** +284 * A node type in the NVD CVE Schema 2.0 +285 */ +286 public static final String VULN_PRODUCT = "vuln:product"; +287 /** +288 * A node type in the NVD CVE Schema 2.0 +289 */ +290 public static final String VULN_REFERENCES = "vuln:references"; +291 /** +292 * A node type in the NVD CVE Schema 2.0 +293 */ +294 public static final String VULN_SOURCE = "vuln:source"; +295 /** +296 * A node type in the NVD CVE Schema 2.0 +297 */ +298 public static final String VULN_REFERENCE = "vuln:reference"; +299 /** +300 * A node type in the NVD CVE Schema 2.0 +301 */ +302 public static final String VULN_SUMMARY = "vuln:summary"; +303 /** +304 * A node type in the NVD CVE Schema 2.0 +305 */ +306 public static final String VULN_CWE = "vuln:cwe"; +307 /** +308 * A node type in the NVD CVE Schema 2.0 +309 */ +310 public static final String CVSS_SCORE = "cvss:score"; +311 /** +312 * A node type in the NVD CVE Schema 2.0 +313 */ +314 public static final String CVSS_ACCESS_VECTOR = "cvss:access-vector"; +315 /** +316 * A node type in the NVD CVE Schema 2.0 +317 */ +318 public static final String CVSS_ACCESS_COMPLEXITY = "cvss:access-complexity"; +319 /** +320 * A node type in the NVD CVE Schema 2.0 +321 */ +322 public static final String CVSS_AUTHENTICATION = "cvss:authentication"; +323 /** +324 * A node type in the NVD CVE Schema 2.0 +325 */ +326 public static final String CVSS_CONFIDENTIALITY_IMPACT = "cvss:confidentiality-impact"; +327 /** +328 * A node type in the NVD CVE Schema 2.0 +329 */ +330 public static final String CVSS_INTEGRITY_IMPACT = "cvss:integrity-impact"; +331 /** +332 * A node type in the NVD CVE Schema 2.0 +333 */ +334 public static final String CVSS_AVAILABILITY_IMPACT = "cvss:availability-impact"; +335 /** +336 * The current node. +337 */ +338 private String node; +339 +340 /** +341 * Gets the value of node. +342 * +343 * @return the value of node +344 */ +345 public String getNode() { +346 return this.node; +347 } +348 +349 /** +350 * Sets the value of node. +351 * +352 * @param node new value of node +353 */ +354 public void setNode(String node) { +355 this.node = node; +356 } +357 +358 /** +359 * Checks if the handler is at the NVD node. +360 * +361 * @return true or false +362 */ +363 public boolean isNVDNode() { +364 return NVD.equals(node); +365 } +366 +367 /** +368 * Checks if the handler is at the ENTRY node. +369 * +370 * @return true or false +371 */ +372 public boolean isEntryNode() { +373 return ENTRY.equals(node); +374 } +375 +376 /** +377 * Checks if the handler is at the VULN_PRODUCT node. +378 * +379 * @return true or false +380 */ +381 public boolean isVulnProductNode() { +382 return VULN_PRODUCT.equals(node); +383 } +384 +385 /** +386 * Checks if the handler is at the REFERENCES node. +387 * +388 * @return true or false +389 */ +390 public boolean isVulnReferencesNode() { +391 return VULN_REFERENCES.equals(node); +392 } +393 +394 /** +395 * Checks if the handler is at the REFERENCE node. +396 * +397 * @return true or false +398 */ +399 public boolean isVulnReferenceNode() { +400 return VULN_REFERENCE.equals(node); +401 } +402 +403 /** +404 * Checks if the handler is at the VULN_SOURCE node. +405 * +406 * @return true or false +407 */ +408 public boolean isVulnSourceNode() { +409 return VULN_SOURCE.equals(node); +410 } +411 +412 /** +413 * Checks if the handler is at the VULN_SUMMARY node. +414 * +415 * @return true or false +416 */ +417 public boolean isVulnSummaryNode() { +418 return VULN_SUMMARY.equals(node); +419 } +420 +421 /** +422 * Checks if the handler is at the VULN_CWE node. +423 * +424 * @return true or false +425 */ +426 public boolean isVulnCWENode() { +427 return VULN_CWE.equals(node); +428 } +429 +430 /** +431 * Checks if the handler is at the CVSS_SCORE node. +432 * +433 * @return true or false +434 */ +435 public boolean isCVSSScoreNode() { +436 return CVSS_SCORE.equals(node); +437 } +438 +439 /** +440 * Checks if the handler is at the CVSS_ACCESS_VECTOR node. +441 * +442 * @return true or false +443 */ +444 public boolean isCVSSAccessVectorNode() { +445 return CVSS_ACCESS_VECTOR.equals(node); +446 } +447 +448 /** +449 * Checks if the handler is at the CVSS_ACCESS_COMPLEXITY node. +450 * +451 * @return true or false +452 */ +453 public boolean isCVSSAccessComplexityNode() { +454 return CVSS_ACCESS_COMPLEXITY.equals(node); +455 } +456 +457 /** +458 * Checks if the handler is at the CVSS_AUTHENTICATION node. +459 * +460 * @return true or false +461 */ +462 public boolean isCVSSAuthenticationNode() { +463 return CVSS_AUTHENTICATION.equals(node); +464 } +465 +466 /** +467 * Checks if the handler is at the CVSS_CONFIDENTIALITY_IMPACT node. +468 * +469 * @return true or false +470 */ +471 public boolean isCVSSConfidentialityImpactNode() { +472 return CVSS_CONFIDENTIALITY_IMPACT.equals(node); +473 } +474 +475 /** +476 * Checks if the handler is at the CVSS_INTEGRITY_IMPACT node. +477 * +478 * @return true or false +479 */ +480 public boolean isCVSSIntegrityImpactNode() { +481 return CVSS_INTEGRITY_IMPACT.equals(node); +482 } +483 +484 /** +485 * Checks if the handler is at the CVSS_AVAILABILITY_IMPACT node. +486 * +487 * @return true or false +488 */ +489 public boolean isCVSSAvailabilityImpactNode() { +490 return CVSS_AVAILABILITY_IMPACT.equals(node); +491 } +492 } +493 // </editor-fold> +494 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html index 59376923d..de11f6060 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html index 70b9753ed..390bfcc25 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-frame.html index 5375e6b00..5c62524c9 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-summary.html index 1fc1fe749..890dff6ea 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Dependency.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Dependency.html index 141da3262..1b976840a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Dependency.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Dependency.html @@ -44,740 +44,783 @@ 36 import org.slf4j.LoggerFactory; 37 38 /** -39 * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about -40 * the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published, -41 * vulnerabilities associated with the program dependency. -42 * -43 * @author Jeremy Long -44 */ -45 public class Dependency implements Serializable, Comparable<Dependency> { -46 -47 /** -48 * The serial version UID for serialization. -49 */ -50 private static final long serialVersionUID = 1L; -51 /** -52 * The logger. -53 */ -54 private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class); -55 /** -56 * Used as starting point for generating the value in {@link #hashCode()}. -57 */ -58 private static final int MAGIC_HASH_INIT_VALUE = 3; -59 /** -60 * Used as a multiplier for generating the value in {@link #hashCode()}. -61 */ -62 private static final int MAGIC_HASH_MULTIPLIER = 47; -63 /** -64 * The actual file path of the dependency on disk. -65 */ -66 private String actualFilePath; -67 /** -68 * The file path to display. -69 */ -70 private String filePath; -71 /** -72 * The file name of the dependency. -73 */ -74 private String fileName; -75 /** -76 * The md5 hash of the dependency. -77 */ -78 private String md5sum; -79 /** -80 * The SHA1 hash of the dependency. -81 */ -82 private String sha1sum; -83 /** -84 * A list of Identifiers. -85 */ -86 private Set<Identifier> identifiers; -87 /** -88 * A collection of vendor evidence. -89 */ -90 private final EvidenceCollection vendorEvidence; +39 * A program dependency. This object is one of the core components within +40 * DependencyCheck. It is used to collect information about the dependency in +41 * the form of evidence. The Evidence is then used to determine if there are any +42 * known, published, vulnerabilities associated with the program dependency. +43 * +44 * @author Jeremy Long +45 */ +46 public class Dependency implements Serializable, Comparable<Dependency> { +47 +48 /** +49 * The serial version UID for serialization. +50 */ +51 private static final long serialVersionUID = 1L; +52 /** +53 * The logger. +54 */ +55 private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class); +56 /** +57 * Used as starting point for generating the value in {@link #hashCode()}. +58 */ +59 private static final int MAGIC_HASH_INIT_VALUE = 3; +60 /** +61 * Used as a multiplier for generating the value in {@link #hashCode()}. +62 */ +63 private static final int MAGIC_HASH_MULTIPLIER = 47; +64 /** +65 * The actual file path of the dependency on disk. +66 */ +67 private String actualFilePath; +68 /** +69 * The file path to display. +70 */ +71 private String filePath; +72 /** +73 * The file name of the dependency. +74 */ +75 private String fileName; +76 +77 /** +78 * The package path. +79 */ +80 private String packagePath; +81 +82 /** +83 * Returns the package path. +84 * +85 * @return the package path +86 */ +87 public String getPackagePath() { +88 return packagePath; +89 } +90 91 /** -92 * A collection of product evidence. -93 */ -94 private final EvidenceCollection productEvidence; -95 /** -96 * A collection of version evidence. -97 */ -98 private final EvidenceCollection versionEvidence; +92 * Sets the package path. +93 * +94 * @param packagePath the package path +95 */ +96 public void setPackagePath(String packagePath) { +97 this.packagePath = packagePath; +98 } 99 100 /** -101 * Constructs a new Dependency object. +101 * The md5 hash of the dependency. 102 */ -103 public Dependency() { -104 vendorEvidence = new EvidenceCollection(); -105 productEvidence = new EvidenceCollection(); -106 versionEvidence = new EvidenceCollection(); -107 identifiers = new TreeSet<Identifier>(); -108 vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); -109 suppressedIdentifiers = new TreeSet<Identifier>(); -110 suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); -111 } -112 -113 /** -114 * Constructs a new Dependency object. -115 * -116 * @param file the File to create the dependency object from. -117 */ -118 public Dependency(File file) { -119 this(); -120 this.actualFilePath = file.getAbsolutePath(); -121 this.filePath = this.actualFilePath; -122 this.fileName = file.getName(); -123 determineHashes(file); -124 } -125 -126 /** -127 * Returns the file name of the dependency. -128 * -129 * @return the file name of the dependency -130 */ -131 public String getFileName() { -132 return this.fileName; -133 } -134 -135 /** -136 * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I -137 * could not get the replace to work in the template itself. -138 * -139 * @return the file name of the dependency with the backslash escaped for use in JavaScript -140 */ -141 public String getFileNameForJavaScript() { -142 return this.fileName.replace("\\", "\\\\"); -143 } -144 -145 /** -146 * Sets the file name of the dependency. -147 * -148 * @param fileName the file name of the dependency -149 */ -150 public void setFileName(String fileName) { -151 this.fileName = fileName; -152 } -153 -154 /** -155 * Sets the actual file path of the dependency on disk. -156 * -157 * @param actualFilePath the file path of the dependency -158 */ -159 public void setActualFilePath(String actualFilePath) { -160 this.actualFilePath = actualFilePath; -161 if (this.sha1sum == null) { -162 final File file = new File(this.actualFilePath); -163 determineHashes(file); -164 } -165 } -166 -167 /** -168 * Gets the file path of the dependency. -169 * -170 * @return the file path of the dependency -171 */ -172 public String getActualFilePath() { -173 return this.actualFilePath; -174 } -175 -176 /** -177 * Gets a reference to the File object. -178 * -179 * @return the File object -180 */ -181 public File getActualFile() { -182 return new File(this.actualFilePath); -183 } -184 -185 /** -186 * Sets the file path of the dependency. -187 * -188 * @param filePath the file path of the dependency -189 */ -190 public void setFilePath(String filePath) { -191 this.filePath = filePath; -192 } -193 -194 /** -195 * The file name to display in reports. -196 */ -197 private String displayName = null; -198 -199 /** -200 * Sets the file name to display in reports. -201 * -202 * @param displayName the name to display -203 */ -204 public void setDisplayFileName(String displayName) { -205 this.displayName = displayName; -206 } -207 -208 /** -209 * Returns the file name to display in reports; if no display file name has been set it will default to the actual file name. -210 * -211 * @return the file name to display -212 */ -213 public String getDisplayFileName() { -214 if (displayName == null) { -215 return this.fileName; -216 } -217 return this.displayName; -218 } -219 -220 /** -221 * <p> -222 * Gets the file path of the dependency.</p> -223 * <p> -224 * <b>NOTE:</b> This may not be the actual path of the file on disk. The actual path of the file on disk can be obtained via -225 * the getActualFilePath().</p> -226 * -227 * @return the file path of the dependency -228 */ -229 public String getFilePath() { -230 return this.filePath; -231 } -232 -233 /** -234 * Returns the MD5 Checksum of the dependency file. -235 * -236 * @return the MD5 Checksum -237 */ -238 public String getMd5sum() { -239 return this.md5sum; -240 } -241 -242 /** -243 * Sets the MD5 Checksum of the dependency. -244 * -245 * @param md5sum the MD5 Checksum -246 */ -247 public void setMd5sum(String md5sum) { -248 this.md5sum = md5sum; -249 } -250 -251 /** -252 * Returns the SHA1 Checksum of the dependency. -253 * -254 * @return the SHA1 Checksum -255 */ -256 public String getSha1sum() { -257 return this.sha1sum; -258 } -259 -260 /** -261 * Sets the SHA1 Checksum of the dependency. -262 * -263 * @param sha1sum the SHA1 Checksum -264 */ -265 public void setSha1sum(String sha1sum) { -266 this.sha1sum = sha1sum; -267 } -268 -269 /** -270 * Returns a List of Identifiers. -271 * -272 * @return an ArrayList of Identifiers -273 */ -274 public Set<Identifier> getIdentifiers() { -275 return this.identifiers; -276 } -277 -278 /** -279 * Sets a List of Identifiers. -280 * -281 * @param identifiers A list of Identifiers -282 */ -283 public void setIdentifiers(Set<Identifier> identifiers) { -284 this.identifiers = identifiers; -285 } -286 -287 /** -288 * Adds an entry to the list of detected Identifiers for the dependency file. -289 * -290 * @param type the type of identifier (such as CPE) -291 * @param value the value of the identifier -292 * @param url the URL of the identifier -293 */ -294 public void addIdentifier(String type, String value, String url) { -295 final Identifier i = new Identifier(type, value, url); -296 this.identifiers.add(i); -297 } -298 -299 /** -300 * Adds an entry to the list of detected Identifiers for the dependency file. -301 * -302 * @param type the type of identifier (such as CPE) -303 * @param value the value of the identifier -304 * @param url the URL of the identifier -305 * @param confidence the confidence in the Identifier being accurate +103 private String md5sum; +104 /** +105 * The SHA1 hash of the dependency. +106 */ +107 private String sha1sum; +108 /** +109 * A list of Identifiers. +110 */ +111 private Set<Identifier> identifiers; +112 /** +113 * A collection of vendor evidence. +114 */ +115 private final EvidenceCollection vendorEvidence; +116 /** +117 * A collection of product evidence. +118 */ +119 private final EvidenceCollection productEvidence; +120 /** +121 * A collection of version evidence. +122 */ +123 private final EvidenceCollection versionEvidence; +124 +125 /** +126 * Constructs a new Dependency object. +127 */ +128 public Dependency() { +129 vendorEvidence = new EvidenceCollection(); +130 productEvidence = new EvidenceCollection(); +131 versionEvidence = new EvidenceCollection(); +132 identifiers = new TreeSet<Identifier>(); +133 vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); +134 suppressedIdentifiers = new TreeSet<Identifier>(); +135 suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); +136 } +137 +138 /** +139 * Constructs a new Dependency object. +140 * +141 * @param file the File to create the dependency object from. +142 */ +143 public Dependency(File file) { +144 this(); +145 this.actualFilePath = file.getAbsolutePath(); +146 this.filePath = this.actualFilePath; +147 this.fileName = file.getName(); +148 this.packagePath = filePath; +149 determineHashes(file); +150 } +151 +152 /** +153 * Returns the file name of the dependency. +154 * +155 * @return the file name of the dependency +156 */ +157 public String getFileName() { +158 return this.fileName; +159 } +160 +161 /** +162 * Returns the file name of the dependency with the backslash escaped for +163 * use in JavaScript. This is a complete hack as I could not get the replace +164 * to work in the template itself. +165 * +166 * @return the file name of the dependency with the backslash escaped for +167 * use in JavaScript +168 */ +169 public String getFileNameForJavaScript() { +170 return this.fileName.replace("\\", "\\\\"); +171 } +172 +173 /** +174 * Sets the file name of the dependency. +175 * +176 * @param fileName the file name of the dependency +177 */ +178 public void setFileName(String fileName) { +179 this.fileName = fileName; +180 } +181 +182 /** +183 * Sets the actual file path of the dependency on disk. +184 * +185 * @param actualFilePath the file path of the dependency +186 */ +187 public void setActualFilePath(String actualFilePath) { +188 this.actualFilePath = actualFilePath; +189 if (this.sha1sum == null) { +190 final File file = new File(this.actualFilePath); +191 determineHashes(file); +192 } +193 } +194 +195 /** +196 * Gets the file path of the dependency. +197 * +198 * @return the file path of the dependency +199 */ +200 public String getActualFilePath() { +201 return this.actualFilePath; +202 } +203 +204 /** +205 * Gets a reference to the File object. +206 * +207 * @return the File object +208 */ +209 public File getActualFile() { +210 return new File(this.actualFilePath); +211 } +212 +213 /** +214 * Sets the file path of the dependency. +215 * +216 * @param filePath the file path of the dependency +217 */ +218 public void setFilePath(String filePath) { +219 if (this.packagePath == null || this.packagePath.equals(this.filePath)) { +220 this.packagePath = filePath; +221 } +222 this.filePath = filePath; +223 } +224 +225 /** +226 * The file name to display in reports. +227 */ +228 private String displayName = null; +229 +230 /** +231 * Sets the file name to display in reports. +232 * +233 * @param displayName the name to display +234 */ +235 public void setDisplayFileName(String displayName) { +236 this.displayName = displayName; +237 } +238 +239 /** +240 * Returns the file name to display in reports; if no display file name has +241 * been set it will default to the actual file name. +242 * +243 * @return the file name to display +244 */ +245 public String getDisplayFileName() { +246 if (displayName == null) { +247 return this.fileName; +248 } +249 return this.displayName; +250 } +251 +252 /** +253 * <p> +254 * Gets the file path of the dependency.</p> +255 * <p> +256 * <b>NOTE:</b> This may not be the actual path of the file on disk. The +257 * actual path of the file on disk can be obtained via the +258 * getActualFilePath().</p> +259 * +260 * @return the file path of the dependency +261 */ +262 public String getFilePath() { +263 return this.filePath; +264 } +265 +266 /** +267 * Returns the MD5 Checksum of the dependency file. +268 * +269 * @return the MD5 Checksum +270 */ +271 public String getMd5sum() { +272 return this.md5sum; +273 } +274 +275 /** +276 * Sets the MD5 Checksum of the dependency. +277 * +278 * @param md5sum the MD5 Checksum +279 */ +280 public void setMd5sum(String md5sum) { +281 this.md5sum = md5sum; +282 } +283 +284 /** +285 * Returns the SHA1 Checksum of the dependency. +286 * +287 * @return the SHA1 Checksum +288 */ +289 public String getSha1sum() { +290 return this.sha1sum; +291 } +292 +293 /** +294 * Sets the SHA1 Checksum of the dependency. +295 * +296 * @param sha1sum the SHA1 Checksum +297 */ +298 public void setSha1sum(String sha1sum) { +299 this.sha1sum = sha1sum; +300 } +301 +302 /** +303 * Returns a List of Identifiers. +304 * +305 * @return an ArrayList of Identifiers 306 */ -307 public void addIdentifier(String type, String value, String url, Confidence confidence) { -308 final Identifier i = new Identifier(type, value, url); -309 i.setConfidence(confidence); -310 this.identifiers.add(i); -311 } -312 -313 /** -314 * Adds the maven artifact as evidence. -315 * -316 * @param source The source of the evidence -317 * @param mavenArtifact The maven artifact -318 * @param confidence The confidence level of this evidence -319 */ -320 public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) { -321 if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) { -322 this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence); -323 } -324 if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) { -325 this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence); -326 } -327 if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) { -328 this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence); -329 } -330 if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) { -331 boolean found = false; -332 for (Identifier i : this.getIdentifiers()) { -333 if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) { -334 found = true; -335 i.setConfidence(Confidence.HIGHEST); -336 final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22"; -337 i.setUrl(url); -338 //i.setUrl(mavenArtifact.getArtifactUrl()); -339 LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue()); -340 break; -341 } -342 } -343 if (!found) { -344 LOGGER.debug("Adding new maven identifier {}", mavenArtifact); -345 this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST); -346 } -347 } -348 } -349 -350 /** -351 * Adds an entry to the list of detected Identifiers for the dependency file. -352 * -353 * @param identifier the identifier to add +307 public Set<Identifier> getIdentifiers() { +308 return this.identifiers; +309 } +310 +311 /** +312 * Sets a List of Identifiers. +313 * +314 * @param identifiers A list of Identifiers +315 */ +316 public void setIdentifiers(Set<Identifier> identifiers) { +317 this.identifiers = identifiers; +318 } +319 +320 /** +321 * Adds an entry to the list of detected Identifiers for the dependency +322 * file. +323 * +324 * @param type the type of identifier (such as CPE) +325 * @param value the value of the identifier +326 * @param url the URL of the identifier +327 */ +328 public void addIdentifier(String type, String value, String url) { +329 final Identifier i = new Identifier(type, value, url); +330 this.identifiers.add(i); +331 } +332 +333 /** +334 * Adds an entry to the list of detected Identifiers for the dependency +335 * file. +336 * +337 * @param type the type of identifier (such as CPE) +338 * @param value the value of the identifier +339 * @param url the URL of the identifier +340 * @param confidence the confidence in the Identifier being accurate +341 */ +342 public void addIdentifier(String type, String value, String url, Confidence confidence) { +343 final Identifier i = new Identifier(type, value, url); +344 i.setConfidence(confidence); +345 this.identifiers.add(i); +346 } +347 +348 /** +349 * Adds the maven artifact as evidence. +350 * +351 * @param source The source of the evidence +352 * @param mavenArtifact The maven artifact +353 * @param confidence The confidence level of this evidence 354 */ -355 public void addIdentifier(Identifier identifier) { -356 this.identifiers.add(identifier); -357 } -358 -359 /** -360 * A set of identifiers that have been suppressed. -361 */ -362 private Set<Identifier> suppressedIdentifiers; -363 -364 /** -365 * Get the value of suppressedIdentifiers. -366 * -367 * @return the value of suppressedIdentifiers -368 */ -369 public Set<Identifier> getSuppressedIdentifiers() { -370 return suppressedIdentifiers; -371 } -372 -373 /** -374 * Set the value of suppressedIdentifiers. -375 * -376 * @param suppressedIdentifiers new value of suppressedIdentifiers -377 */ -378 public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) { -379 this.suppressedIdentifiers = suppressedIdentifiers; -380 } -381 -382 /** -383 * Adds an identifier to the list of suppressed identifiers. -384 * -385 * @param identifier an identifier that was suppressed. -386 */ -387 public void addSuppressedIdentifier(Identifier identifier) { -388 this.suppressedIdentifiers.add(identifier); -389 } -390 -391 /** -392 * A set of vulnerabilities that have been suppressed. -393 */ -394 private SortedSet<Vulnerability> suppressedVulnerabilities; -395 -396 /** -397 * Get the value of suppressedVulnerabilities. -398 * -399 * @return the value of suppressedVulnerabilities -400 */ -401 public SortedSet<Vulnerability> getSuppressedVulnerabilities() { -402 return suppressedVulnerabilities; -403 } -404 -405 /** -406 * Set the value of suppressedVulnerabilities. -407 * -408 * @param suppressedVulnerabilities new value of suppressedVulnerabilities -409 */ -410 public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) { -411 this.suppressedVulnerabilities = suppressedVulnerabilities; -412 } -413 -414 /** -415 * Adds a vulnerability to the set of suppressed vulnerabilities. -416 * -417 * @param vulnerability the vulnerability that was suppressed -418 */ -419 public void addSuppressedVulnerability(Vulnerability vulnerability) { -420 this.suppressedVulnerabilities.add(vulnerability); -421 } -422 -423 /** -424 * Returns the evidence used to identify this dependency. -425 * -426 * @return an EvidenceCollection. -427 */ -428 public EvidenceCollection getEvidence() { -429 return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence); -430 } +355 public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) { +356 if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) { +357 this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence); +358 } +359 if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) { +360 this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence); +361 } +362 if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) { +363 this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence); +364 } +365 if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) { +366 boolean found = false; +367 for (Identifier i : this.getIdentifiers()) { +368 if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) { +369 found = true; +370 i.setConfidence(Confidence.HIGHEST); +371 final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22"; +372 i.setUrl(url); +373 //i.setUrl(mavenArtifact.getArtifactUrl()); +374 LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue()); +375 break; +376 } +377 } +378 if (!found) { +379 LOGGER.debug("Adding new maven identifier {}", mavenArtifact); +380 this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST); +381 } +382 } +383 } +384 +385 /** +386 * Adds an entry to the list of detected Identifiers for the dependency +387 * file. +388 * +389 * @param identifier the identifier to add +390 */ +391 public void addIdentifier(Identifier identifier) { +392 this.identifiers.add(identifier); +393 } +394 +395 /** +396 * A set of identifiers that have been suppressed. +397 */ +398 private Set<Identifier> suppressedIdentifiers; +399 +400 /** +401 * Get the value of suppressedIdentifiers. +402 * +403 * @return the value of suppressedIdentifiers +404 */ +405 public Set<Identifier> getSuppressedIdentifiers() { +406 return suppressedIdentifiers; +407 } +408 +409 /** +410 * Set the value of suppressedIdentifiers. +411 * +412 * @param suppressedIdentifiers new value of suppressedIdentifiers +413 */ +414 public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) { +415 this.suppressedIdentifiers = suppressedIdentifiers; +416 } +417 +418 /** +419 * Adds an identifier to the list of suppressed identifiers. +420 * +421 * @param identifier an identifier that was suppressed. +422 */ +423 public void addSuppressedIdentifier(Identifier identifier) { +424 this.suppressedIdentifiers.add(identifier); +425 } +426 +427 /** +428 * A set of vulnerabilities that have been suppressed. +429 */ +430 private SortedSet<Vulnerability> suppressedVulnerabilities; 431 432 /** -433 * Returns the evidence used to identify this dependency. +433 * Get the value of suppressedVulnerabilities. 434 * -435 * @return an EvidenceCollection. +435 * @return the value of suppressedVulnerabilities 436 */ -437 public Set<Evidence> getEvidenceForDisplay() { -438 return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence); +437 public SortedSet<Vulnerability> getSuppressedVulnerabilities() { +438 return suppressedVulnerabilities; 439 } 440 441 /** -442 * Returns the evidence used to identify this dependency. +442 * Set the value of suppressedVulnerabilities. 443 * -444 * @return an EvidenceCollection. +444 * @param suppressedVulnerabilities new value of suppressedVulnerabilities 445 */ -446 public EvidenceCollection getEvidenceUsed() { -447 return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence); +446 public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) { +447 this.suppressedVulnerabilities = suppressedVulnerabilities; 448 } 449 450 /** -451 * Gets the Vendor Evidence. +451 * Adds a vulnerability to the set of suppressed vulnerabilities. 452 * -453 * @return an EvidenceCollection. +453 * @param vulnerability the vulnerability that was suppressed 454 */ -455 public EvidenceCollection getVendorEvidence() { -456 return this.vendorEvidence; +455 public void addSuppressedVulnerability(Vulnerability vulnerability) { +456 this.suppressedVulnerabilities.add(vulnerability); 457 } 458 459 /** -460 * Gets the Product Evidence. +460 * Returns the evidence used to identify this dependency. 461 * 462 * @return an EvidenceCollection. 463 */ -464 public EvidenceCollection getProductEvidence() { -465 return this.productEvidence; +464 public EvidenceCollection getEvidence() { +465 return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence); 466 } 467 468 /** -469 * Gets the Version Evidence. +469 * Returns the evidence used to identify this dependency. 470 * 471 * @return an EvidenceCollection. 472 */ -473 public EvidenceCollection getVersionEvidence() { -474 return this.versionEvidence; +473 public Set<Evidence> getEvidenceForDisplay() { +474 return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence); 475 } 476 477 /** -478 * The description of the JAR file. -479 */ -480 private String description; -481 -482 /** -483 * Get the value of description. -484 * -485 * @return the value of description -486 */ -487 public String getDescription() { -488 return description; -489 } -490 -491 /** -492 * Set the value of description. -493 * -494 * @param description new value of description -495 */ -496 public void setDescription(String description) { -497 this.description = description; -498 } -499 -500 /** -501 * The license that this dependency uses. -502 */ -503 private String license; -504 -505 /** -506 * Get the value of license. -507 * -508 * @return the value of license -509 */ -510 public String getLicense() { -511 return license; -512 } -513 -514 /** -515 * Set the value of license. -516 * -517 * @param license new value of license -518 */ -519 public void setLicense(String license) { -520 this.license = license; -521 } -522 -523 /** -524 * A list of vulnerabilities for this dependency. -525 */ -526 private SortedSet<Vulnerability> vulnerabilities; -527 -528 /** -529 * Get the list of vulnerabilities. -530 * -531 * @return the list of vulnerabilities -532 */ -533 public SortedSet<Vulnerability> getVulnerabilities() { -534 return vulnerabilities; -535 } -536 -537 /** -538 * Set the value of vulnerabilities. -539 * -540 * @param vulnerabilities new value of vulnerabilities -541 */ -542 public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) { -543 this.vulnerabilities = vulnerabilities; -544 } -545 -546 /** -547 * Determines the sha1 and md5 sum for the given file. -548 * -549 * @param file the file to create checksums for -550 */ -551 private void determineHashes(File file) { -552 String md5 = null; -553 String sha1 = null; -554 try { -555 md5 = Checksum.getMD5Checksum(file); -556 sha1 = Checksum.getSHA1Checksum(file); -557 } catch (IOException ex) { -558 LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName()); -559 LOGGER.debug("", ex); -560 } catch (NoSuchAlgorithmException ex) { -561 LOGGER.warn("Unable to use MD5 of SHA1 checksums."); -562 LOGGER.debug("", ex); -563 } -564 this.setMd5sum(md5); -565 this.setSha1sum(sha1); -566 } -567 -568 /** -569 * Adds a vulnerability to the dependency. -570 * -571 * @param vulnerability a vulnerability outlining a vulnerability. -572 */ -573 public void addVulnerability(Vulnerability vulnerability) { -574 this.vulnerabilities.add(vulnerability); -575 } -576 -577 /** -578 * A collection of related dependencies. -579 */ -580 private Set<Dependency> relatedDependencies = new TreeSet<Dependency>(); +478 * Returns the evidence used to identify this dependency. +479 * +480 * @return an EvidenceCollection. +481 */ +482 public EvidenceCollection getEvidenceUsed() { +483 return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence); +484 } +485 +486 /** +487 * Gets the Vendor Evidence. +488 * +489 * @return an EvidenceCollection. +490 */ +491 public EvidenceCollection getVendorEvidence() { +492 return this.vendorEvidence; +493 } +494 +495 /** +496 * Gets the Product Evidence. +497 * +498 * @return an EvidenceCollection. +499 */ +500 public EvidenceCollection getProductEvidence() { +501 return this.productEvidence; +502 } +503 +504 /** +505 * Gets the Version Evidence. +506 * +507 * @return an EvidenceCollection. +508 */ +509 public EvidenceCollection getVersionEvidence() { +510 return this.versionEvidence; +511 } +512 +513 /** +514 * The description of the JAR file. +515 */ +516 private String description; +517 +518 /** +519 * Get the value of description. +520 * +521 * @return the value of description +522 */ +523 public String getDescription() { +524 return description; +525 } +526 +527 /** +528 * Set the value of description. +529 * +530 * @param description new value of description +531 */ +532 public void setDescription(String description) { +533 this.description = description; +534 } +535 +536 /** +537 * The license that this dependency uses. +538 */ +539 private String license; +540 +541 /** +542 * Get the value of license. +543 * +544 * @return the value of license +545 */ +546 public String getLicense() { +547 return license; +548 } +549 +550 /** +551 * Set the value of license. +552 * +553 * @param license new value of license +554 */ +555 public void setLicense(String license) { +556 this.license = license; +557 } +558 +559 /** +560 * A list of vulnerabilities for this dependency. +561 */ +562 private SortedSet<Vulnerability> vulnerabilities; +563 +564 /** +565 * Get the list of vulnerabilities. +566 * +567 * @return the list of vulnerabilities +568 */ +569 public SortedSet<Vulnerability> getVulnerabilities() { +570 return vulnerabilities; +571 } +572 +573 /** +574 * Set the value of vulnerabilities. +575 * +576 * @param vulnerabilities new value of vulnerabilities +577 */ +578 public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) { +579 this.vulnerabilities = vulnerabilities; +580 } 581 582 /** -583 * Get the value of {@link #relatedDependencies}. This field is used to collect other dependencies which really represent the -584 * same dependency, and may be presented as one item in reports. -585 * -586 * @return the value of relatedDependencies -587 */ -588 public Set<Dependency> getRelatedDependencies() { -589 return relatedDependencies; -590 } -591 -592 /** -593 * A list of projects that reference this dependency. -594 */ -595 private Set<String> projectReferences = new HashSet<String>(); -596 -597 /** -598 * Get the value of projectReferences. -599 * -600 * @return the value of projectReferences -601 */ -602 public Set<String> getProjectReferences() { -603 return projectReferences; -604 } -605 -606 /** -607 * Set the value of projectReferences. -608 * -609 * @param projectReferences new value of projectReferences -610 */ -611 public void setProjectReferences(Set<String> projectReferences) { -612 this.projectReferences = projectReferences; -613 } -614 -615 /** -616 * Adds a project reference. -617 * -618 * @param projectReference a project reference -619 */ -620 public void addProjectReference(String projectReference) { -621 this.projectReferences.add(projectReference); -622 } -623 -624 /** -625 * Add a collection of project reference. -626 * -627 * @param projectReferences a set of project references -628 */ -629 public void addAllProjectReferences(Set<String> projectReferences) { -630 this.projectReferences.addAll(projectReferences); -631 } -632 -633 /** -634 * Set the value of relatedDependencies. -635 * -636 * @param relatedDependencies new value of relatedDependencies -637 */ -638 public void setRelatedDependencies(Set<Dependency> relatedDependencies) { -639 this.relatedDependencies = relatedDependencies; -640 } -641 -642 /** -643 * Adds a related dependency. The internal collection is normally a {@link java.util.TreeSet}, which relies on -644 * {@link #compareTo(Dependency)}. A consequence of this is that if you attempt to add a dependency with the same file path -645 * (modulo character case) as one that is already in the collection, it won't get added. -646 * -647 * @param dependency a reference to the related dependency -648 */ -649 public void addRelatedDependency(Dependency dependency) { -650 if (this == dependency) { -651 LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here " -652 + "https://github.com/jeremylong/DependencyCheck/issues/172"); -653 LOGGER.debug("this: {}", this); -654 LOGGER.debug("dependency: {}", dependency); -655 } else if (!relatedDependencies.add(dependency)) { -656 LOGGER.debug("Failed to add dependency, likely due to referencing the same file as another dependency in the set."); -657 LOGGER.debug("this: {}", this); -658 LOGGER.debug("dependency: {}", dependency); -659 } -660 } -661 -662 /** -663 * A list of available versions. -664 */ -665 private List<String> availableVersions = new ArrayList<String>(); -666 -667 /** -668 * Get the value of availableVersions. -669 * -670 * @return the value of availableVersions -671 */ -672 public List<String> getAvailableVersions() { -673 return availableVersions; -674 } -675 -676 /** -677 * Set the value of availableVersions. -678 * -679 * @param availableVersions new value of availableVersions -680 */ -681 public void setAvailableVersions(List<String> availableVersions) { -682 this.availableVersions = availableVersions; -683 } -684 -685 /** -686 * Adds a version to the available version list. -687 * -688 * @param version the version to add to the list -689 */ -690 public void addAvailableVersion(String version) { -691 this.availableVersions.add(version); -692 } -693 -694 /** -695 * Implementation of the Comparable&lt;Dependency&gt; interface. The comparison is solely based on the file path. -696 * -697 * @param o a dependency to compare -698 * @return an integer representing the natural ordering -699 */ -700 @Override -701 public int compareTo(Dependency o) { -702 return this.getFilePath().compareToIgnoreCase(o.getFilePath()); -703 } -704 -705 /** -706 * Implementation of the equals method. -707 * -708 * @param obj the object to compare -709 * @return true if the objects are equal, otherwise false +583 * Determines the sha1 and md5 sum for the given file. +584 * +585 * @param file the file to create checksums for +586 */ +587 private void determineHashes(File file) { +588 String md5 = null; +589 String sha1 = null; +590 try { +591 md5 = Checksum.getMD5Checksum(file); +592 sha1 = Checksum.getSHA1Checksum(file); +593 } catch (IOException ex) { +594 LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName()); +595 LOGGER.debug("", ex); +596 } catch (NoSuchAlgorithmException ex) { +597 LOGGER.warn("Unable to use MD5 of SHA1 checksums."); +598 LOGGER.debug("", ex); +599 } +600 this.setMd5sum(md5); +601 this.setSha1sum(sha1); +602 } +603 +604 /** +605 * Adds a vulnerability to the dependency. +606 * +607 * @param vulnerability a vulnerability outlining a vulnerability. +608 */ +609 public void addVulnerability(Vulnerability vulnerability) { +610 this.vulnerabilities.add(vulnerability); +611 } +612 +613 /** +614 * A collection of related dependencies. +615 */ +616 private Set<Dependency> relatedDependencies = new TreeSet<Dependency>(); +617 +618 /** +619 * Get the value of {@link #relatedDependencies}. This field is used to +620 * collect other dependencies which really represent the same dependency, +621 * and may be presented as one item in reports. +622 * +623 * @return the value of relatedDependencies +624 */ +625 public Set<Dependency> getRelatedDependencies() { +626 return relatedDependencies; +627 } +628 +629 /** +630 * A list of projects that reference this dependency. +631 */ +632 private Set<String> projectReferences = new HashSet<String>(); +633 +634 /** +635 * Get the value of projectReferences. +636 * +637 * @return the value of projectReferences +638 */ +639 public Set<String> getProjectReferences() { +640 return projectReferences; +641 } +642 +643 /** +644 * Set the value of projectReferences. +645 * +646 * @param projectReferences new value of projectReferences +647 */ +648 public void setProjectReferences(Set<String> projectReferences) { +649 this.projectReferences = projectReferences; +650 } +651 +652 /** +653 * Adds a project reference. +654 * +655 * @param projectReference a project reference +656 */ +657 public void addProjectReference(String projectReference) { +658 this.projectReferences.add(projectReference); +659 } +660 +661 /** +662 * Add a collection of project reference. +663 * +664 * @param projectReferences a set of project references +665 */ +666 public void addAllProjectReferences(Set<String> projectReferences) { +667 this.projectReferences.addAll(projectReferences); +668 } +669 +670 /** +671 * Set the value of relatedDependencies. +672 * +673 * @param relatedDependencies new value of relatedDependencies +674 */ +675 public void setRelatedDependencies(Set<Dependency> relatedDependencies) { +676 this.relatedDependencies = relatedDependencies; +677 } +678 +679 /** +680 * Adds a related dependency. The internal collection is normally a +681 * {@link java.util.TreeSet}, which relies on +682 * {@link #compareTo(Dependency)}. A consequence of this is that if you +683 * attempt to add a dependency with the same file path (modulo character +684 * case) as one that is already in the collection, it won't get added. +685 * +686 * @param dependency a reference to the related dependency +687 */ +688 public void addRelatedDependency(Dependency dependency) { +689 if (this == dependency) { +690 LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here " +691 + "https://github.com/jeremylong/DependencyCheck/issues/172"); +692 LOGGER.debug("this: {}", this); +693 LOGGER.debug("dependency: {}", dependency); +694 } else if (!relatedDependencies.add(dependency)) { +695 LOGGER.debug("Failed to add dependency, likely due to referencing the same file as another dependency in the set."); +696 LOGGER.debug("this: {}", this); +697 LOGGER.debug("dependency: {}", dependency); +698 } +699 } +700 +701 /** +702 * A list of available versions. +703 */ +704 private List<String> availableVersions = new ArrayList<String>(); +705 +706 /** +707 * Get the value of availableVersions. +708 * +709 * @return the value of availableVersions 710 */ -711 @Override -712 public boolean equals(Object obj) { -713 if (obj == null || getClass() != obj.getClass()) { -714 return false; -715 } -716 final Dependency other = (Dependency) obj; -717 return new EqualsBuilder() -718 .appendSuper(super.equals(obj)) -719 .append(this.actualFilePath, other.actualFilePath) -720 .append(this.filePath, other.filePath) -721 .append(this.fileName, other.fileName) -722 .append(this.md5sum, other.md5sum) -723 .append(this.sha1sum, other.sha1sum) -724 .append(this.identifiers, other.identifiers) -725 .append(this.vendorEvidence, other.vendorEvidence) -726 .append(this.productEvidence, other.productEvidence) -727 .append(this.versionEvidence, other.versionEvidence) -728 .append(this.description, other.description) -729 .append(this.license, other.license) -730 .append(this.vulnerabilities, other.vulnerabilities) -731 //.append(this.relatedDependencies, other.relatedDependencies) -732 .append(this.projectReferences, other.projectReferences) -733 .append(this.availableVersions, other.availableVersions) -734 .isEquals(); -735 } -736 -737 /** -738 * Generates the HashCode. -739 * -740 * @return the HashCode -741 */ -742 @Override -743 public int hashCode() { -744 return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER) -745 .append(actualFilePath) -746 .append(filePath) -747 .append(fileName) -748 .append(md5sum) -749 .append(sha1sum) -750 .append(identifiers) -751 .append(vendorEvidence) -752 .append(productEvidence) -753 .append(versionEvidence) -754 .append(description) -755 .append(license) -756 .append(vulnerabilities) -757 //.append(relatedDependencies) -758 .append(projectReferences) -759 .append(availableVersions) -760 .toHashCode(); -761 } -762 -763 /** -764 * Standard toString() implementation showing the filename, actualFilePath, and filePath. -765 * -766 * @return the string representation of the file -767 */ -768 @Override -769 public String toString() { -770 return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}"; -771 } -772 } +711 public List<String> getAvailableVersions() { +712 return availableVersions; +713 } +714 +715 /** +716 * Set the value of availableVersions. +717 * +718 * @param availableVersions new value of availableVersions +719 */ +720 public void setAvailableVersions(List<String> availableVersions) { +721 this.availableVersions = availableVersions; +722 } +723 +724 /** +725 * Adds a version to the available version list. +726 * +727 * @param version the version to add to the list +728 */ +729 public void addAvailableVersion(String version) { +730 this.availableVersions.add(version); +731 } +732 +733 /** +734 * Implementation of the Comparable&lt;Dependency&gt; interface. The +735 * comparison is solely based on the file path. +736 * +737 * @param o a dependency to compare +738 * @return an integer representing the natural ordering +739 */ +740 @Override +741 public int compareTo(Dependency o) { +742 return this.getFilePath().compareToIgnoreCase(o.getFilePath()); +743 } +744 +745 /** +746 * Implementation of the equals method. +747 * +748 * @param obj the object to compare +749 * @return true if the objects are equal, otherwise false +750 */ +751 @Override +752 public boolean equals(Object obj) { +753 if (obj == null || getClass() != obj.getClass()) { +754 return false; +755 } +756 final Dependency other = (Dependency) obj; +757 return new EqualsBuilder() +758 .appendSuper(super.equals(obj)) +759 .append(this.actualFilePath, other.actualFilePath) +760 .append(this.filePath, other.filePath) +761 .append(this.fileName, other.fileName) +762 .append(this.packagePath, other.packagePath) +763 .append(this.md5sum, other.md5sum) +764 .append(this.sha1sum, other.sha1sum) +765 .append(this.identifiers, other.identifiers) +766 .append(this.vendorEvidence, other.vendorEvidence) +767 .append(this.productEvidence, other.productEvidence) +768 .append(this.versionEvidence, other.versionEvidence) +769 .append(this.description, other.description) +770 .append(this.license, other.license) +771 .append(this.vulnerabilities, other.vulnerabilities) +772 //.append(this.relatedDependencies, other.relatedDependencies) +773 .append(this.projectReferences, other.projectReferences) +774 .append(this.availableVersions, other.availableVersions) +775 .isEquals(); +776 } +777 +778 /** +779 * Generates the HashCode. +780 * +781 * @return the HashCode +782 */ +783 @Override +784 public int hashCode() { +785 return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER) +786 .append(actualFilePath) +787 .append(filePath) +788 .append(fileName) +789 .append(md5sum) +790 .append(sha1sum) +791 .append(identifiers) +792 .append(vendorEvidence) +793 .append(productEvidence) +794 .append(versionEvidence) +795 .append(description) +796 .append(license) +797 .append(vulnerabilities) +798 //.append(relatedDependencies) +799 .append(projectReferences) +800 .append(availableVersions) +801 .toHashCode(); +802 } +803 +804 /** +805 * Standard toString() implementation showing the filename, actualFilePath, +806 * and filePath. +807 * +808 * @return the string representation of the file +809 */ +810 @Override +811 public String toString() { +812 return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath +813 + "', filePath='" + filePath + "', packagePath='" + packagePath + "'}"; +814 } +815 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Reference.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Reference.html index 4bb97c302..2230c6e7a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Reference.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Reference.html @@ -28,136 +28,142 @@ 20 import java.io.Serializable; 21 22 /** -23 * An external reference for a vulnerability. This contains a name, URL, and a source. -24 * -25 * @author Jeremy Long -26 */ -27 public class Reference implements Serializable, Comparable<Reference> { -28 -29 /** -30 * the serial version uid. -31 */ -32 private static final long serialVersionUID = -3444464824563008021L; -33 /** -34 * The name of the reference. -35 */ -36 private String name; -37 -38 /** -39 * Get the value of name. -40 * -41 * @return the value of name -42 */ -43 public String getName() { -44 return name; -45 } -46 -47 /** -48 * Set the value of name. -49 * -50 * @param name new value of name -51 */ -52 public void setName(String name) { -53 this.name = name; -54 } -55 /** -56 * the url for the reference. -57 */ -58 private String url; -59 -60 /** -61 * Get the value of url. -62 * -63 * @return the value of url -64 */ -65 public String getUrl() { -66 return url; -67 } -68 -69 /** -70 * Set the value of url. -71 * -72 * @param url new value of url -73 */ -74 public void setUrl(String url) { -75 this.url = url; -76 } -77 /** -78 * the source of the reference. -79 */ -80 private String source; -81 -82 /** -83 * Get the value of source. -84 * -85 * @return the value of source -86 */ -87 public String getSource() { -88 return source; -89 } -90 -91 /** -92 * Set the value of source. -93 * -94 * @param source new value of source -95 */ -96 public void setSource(String source) { -97 this.source = source; -98 } -99 -100 @Override -101 public boolean equals(Object obj) { -102 if (obj == null) { -103 return false; -104 } -105 if (getClass() != obj.getClass()) { -106 return false; -107 } -108 final Reference other = (Reference) obj; -109 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { -110 return false; -111 } -112 if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) { -113 return false; -114 } -115 if ((this.source == null) ? (other.source != null) : !this.source.equals(other.source)) { +23 * An external reference for a vulnerability. This contains a name, URL, and a +24 * source. +25 * +26 * @author Jeremy Long +27 */ +28 public class Reference implements Serializable, Comparable<Reference> { +29 +30 /** +31 * the serial version uid. +32 */ +33 private static final long serialVersionUID = -3444464824563008021L; +34 /** +35 * The name of the reference. +36 */ +37 private String name; +38 +39 /** +40 * Get the value of name. +41 * +42 * @return the value of name +43 */ +44 public String getName() { +45 return name; +46 } +47 +48 /** +49 * Set the value of name. +50 * +51 * @param name new value of name +52 */ +53 public void setName(String name) { +54 this.name = name; +55 } +56 /** +57 * the url for the reference. +58 */ +59 private String url; +60 +61 /** +62 * Get the value of url. +63 * +64 * @return the value of url +65 */ +66 public String getUrl() { +67 return url; +68 } +69 +70 /** +71 * Set the value of url. +72 * +73 * @param url new value of url +74 */ +75 public void setUrl(String url) { +76 this.url = url; +77 } +78 /** +79 * the source of the reference. +80 */ +81 private String source; +82 +83 /** +84 * Get the value of source. +85 * +86 * @return the value of source +87 */ +88 public String getSource() { +89 return source; +90 } +91 +92 /** +93 * Set the value of source. +94 * +95 * @param source new value of source +96 */ +97 public void setSource(String source) { +98 this.source = source; +99 } +100 +101 @Override +102 public String toString() { +103 return "Reference: { name='" + this.name + "', url='" + this.url + "', source='" + this.source + "' }"; +104 } +105 +106 @Override +107 public boolean equals(Object obj) { +108 if (obj == null) { +109 return false; +110 } +111 if (getClass() != obj.getClass()) { +112 return false; +113 } +114 final Reference other = (Reference) obj; +115 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { 116 return false; 117 } -118 return true; -119 } -120 -121 @Override -122 public int hashCode() { -123 int hash = 5; -124 hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0); -125 hash = 67 * hash + (this.url != null ? this.url.hashCode() : 0); -126 hash = 67 * hash + (this.source != null ? this.source.hashCode() : 0); -127 return hash; -128 } -129 -130 /** -131 * Implementation of the comparable interface. -132 * -133 * @param o the Reference being compared -134 * @return an integer indicating the ordering of the two objects -135 */ -136 @Override -137 public int compareTo(Reference o) { -138 if (source.equals(o.source)) { -139 if (name.equals(o.name)) { -140 if (url.equals(o.url)) { -141 return 0; //they are equal -142 } else { -143 return url.compareTo(o.url); -144 } -145 } else { -146 return name.compareTo(o.name); -147 } -148 } else { -149 return source.compareTo(o.source); -150 } -151 } -152 } +118 if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) { +119 return false; +120 } +121 if ((this.source == null) ? (other.source != null) : !this.source.equals(other.source)) { +122 return false; +123 } +124 return true; +125 } +126 +127 @Override +128 public int hashCode() { +129 int hash = 5; +130 hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0); +131 hash = 67 * hash + (this.url != null ? this.url.hashCode() : 0); +132 hash = 67 * hash + (this.source != null ? this.source.hashCode() : 0); +133 return hash; +134 } +135 +136 /** +137 * Implementation of the comparable interface. +138 * +139 * @param o the Reference being compared +140 * @return an integer indicating the ordering of the two objects +141 */ +142 @Override +143 public int compareTo(Reference o) { +144 if (source.equals(o.source)) { +145 if (name.equals(o.name)) { +146 if (url.equals(o.url)) { +147 return 0; //they are equal +148 } else { +149 return url.compareTo(o.url); +150 } +151 } else { +152 return name.compareTo(o.name); +153 } +154 } else { +155 return source.compareTo(o.source); +156 } +157 } +158 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Vulnerability.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Vulnerability.html index 5ea536259..f6382c0f0 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Vulnerability.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Vulnerability.html @@ -29,428 +29,448 @@ 21 import java.util.Set; 22 import java.util.SortedSet; 23 import java.util.TreeSet; -24 -25 /** -26 * Contains the information about a vulnerability. -27 * -28 * @author Jeremy Long -29 */ -30 public class Vulnerability implements Serializable, Comparable<Vulnerability> { -31 -32 /** -33 * The serial version uid. -34 */ -35 private static final long serialVersionUID = 307319490326651052L; -36 /** -37 * The name of the vulnerability. -38 */ -39 private String name; -40 -41 /** -42 * Get the value of name. -43 * -44 * @return the value of name -45 */ -46 public String getName() { -47 return name; -48 } -49 -50 /** -51 * Set the value of name. -52 * -53 * @param name new value of name -54 */ -55 public void setName(String name) { -56 this.name = name; -57 } -58 /** -59 * the description of the vulnerability. -60 */ -61 private String description; -62 -63 /** -64 * Get the value of description. -65 * -66 * @return the value of description -67 */ -68 public String getDescription() { -69 return description; -70 } -71 -72 /** -73 * Set the value of description. -74 * -75 * @param description new value of description -76 */ -77 public void setDescription(String description) { -78 this.description = description; -79 } -80 /** -81 * References for this vulnerability. -82 */ -83 private SortedSet<Reference> references = new TreeSet<Reference>(); -84 -85 /** -86 * Get the value of references. -87 * -88 * @return the value of references -89 */ -90 public Set<Reference> getReferences() { -91 return references; -92 } -93 -94 /** -95 * Set the value of references. -96 * -97 * @param references new value of references -98 */ -99 public void setReferences(SortedSet<Reference> references) { -100 this.references = references; -101 } -102 -103 /** -104 * Adds a reference to the references collection. -105 * -106 * @param ref a reference for the vulnerability -107 */ -108 public void addReference(Reference ref) { -109 this.references.add(ref); -110 } -111 -112 /** -113 * Adds a reference. -114 * -115 * @param referenceSource the source of the reference -116 * @param referenceName the referenceName of the reference -117 * @param referenceUrl the url of the reference -118 */ -119 public void addReference(String referenceSource, String referenceName, String referenceUrl) { -120 final Reference ref = new Reference(); -121 ref.setSource(referenceSource); -122 ref.setName(referenceName); -123 ref.setUrl(referenceUrl); -124 this.references.add(ref); -125 } -126 /** -127 * A set of vulnerable software. -128 */ -129 private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>(); -130 -131 /** -132 * Get the value of vulnerableSoftware. -133 * -134 * @return the value of vulnerableSoftware -135 */ -136 public Set<VulnerableSoftware> getVulnerableSoftware() { -137 return vulnerableSoftware; -138 } -139 -140 /** -141 * Set the value of vulnerableSoftware. -142 * -143 * @param vulnerableSoftware new value of vulnerableSoftware -144 */ -145 public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) { -146 this.vulnerableSoftware = vulnerableSoftware; -147 } -148 -149 /** -150 * Adds an entry for vulnerable software. -151 * -152 * @param cpe string representation of a CPE entry -153 * @return if the add succeeded -154 */ -155 public boolean addVulnerableSoftware(String cpe) { -156 return addVulnerableSoftware(cpe, null); -157 } -158 -159 /** -160 * Adds an entry for vulnerable software. -161 * -162 * @param cpe string representation of a cpe -163 * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable) -164 * @return if the add succeeded -165 */ -166 public boolean addVulnerableSoftware(String cpe, String previousVersion) { -167 final VulnerableSoftware vs = new VulnerableSoftware(); -168 vs.setCpe(cpe); -169 if (previousVersion != null) { -170 vs.setPreviousVersion(previousVersion); -171 } -172 return updateVulnerableSoftware(vs); -173 } -174 -175 /** -176 * Adds or updates a vulnerable software entry. -177 * -178 * @param vulnSoftware the vulnerable software -179 * @return if the update succeeded -180 */ -181 public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) { -182 if (vulnerableSoftware.contains(vulnSoftware)) { -183 vulnerableSoftware.remove(vulnSoftware); -184 } -185 return vulnerableSoftware.add(vulnSoftware); -186 } -187 /** -188 * The CWE for the vulnerability. -189 */ -190 private String cwe; -191 -192 /** -193 * Get the value of cwe. -194 * -195 * @return the value of cwe -196 */ -197 public String getCwe() { -198 return cwe; -199 } -200 -201 /** -202 * Set the value of cwe. -203 * -204 * @param cwe new value of cwe -205 */ -206 public void setCwe(String cwe) { -207 this.cwe = cwe; -208 } -209 /** -210 * CVSS Score. -211 */ -212 private float cvssScore; -213 -214 /** -215 * Get the value of cvssScore. -216 * -217 * @return the value of cvssScore -218 */ -219 public float getCvssScore() { -220 return cvssScore; -221 } -222 -223 /** -224 * Set the value of cvssScore. -225 * -226 * @param cvssScore new value of cvssScore -227 */ -228 public void setCvssScore(float cvssScore) { -229 this.cvssScore = cvssScore; -230 } -231 /** -232 * CVSS Access Vector. -233 */ -234 private String cvssAccessVector; -235 -236 /** -237 * Get the value of cvssAccessVector. -238 * -239 * @return the value of cvssAccessVector -240 */ -241 public String getCvssAccessVector() { -242 return cvssAccessVector; -243 } -244 -245 /** -246 * Set the value of cvssAccessVector. -247 * -248 * @param cvssAccessVector new value of cvssAccessVector -249 */ -250 public void setCvssAccessVector(String cvssAccessVector) { -251 this.cvssAccessVector = cvssAccessVector; -252 } -253 /** -254 * CVSS Access Complexity. -255 */ -256 private String cvssAccessComplexity; -257 -258 /** -259 * Get the value of cvssAccessComplexity. -260 * -261 * @return the value of cvssAccessComplexity -262 */ -263 public String getCvssAccessComplexity() { -264 return cvssAccessComplexity; -265 } -266 -267 /** -268 * Set the value of cvssAccessComplexity. -269 * -270 * @param cvssAccessComplexity new value of cvssAccessComplexity -271 */ -272 public void setCvssAccessComplexity(String cvssAccessComplexity) { -273 this.cvssAccessComplexity = cvssAccessComplexity; -274 } -275 /** -276 * CVSS Authentication. -277 */ -278 private String cvssAuthentication; -279 -280 /** -281 * Get the value of cvssAuthentication. -282 * -283 * @return the value of cvssAuthentication -284 */ -285 public String getCvssAuthentication() { -286 return cvssAuthentication; -287 } -288 -289 /** -290 * Set the value of cvssAuthentication. -291 * -292 * @param cvssAuthentication new value of cvssAuthentication -293 */ -294 public void setCvssAuthentication(String cvssAuthentication) { -295 this.cvssAuthentication = cvssAuthentication; -296 } -297 /** -298 * CVSS Confidentiality Impact. -299 */ -300 private String cvssConfidentialityImpact; -301 -302 /** -303 * Get the value of cvssConfidentialityImpact. -304 * -305 * @return the value of cvssConfidentialityImpact -306 */ -307 public String getCvssConfidentialityImpact() { -308 return cvssConfidentialityImpact; -309 } -310 -311 /** -312 * Set the value of cvssConfidentialityImpact. -313 * -314 * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact -315 */ -316 public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) { -317 this.cvssConfidentialityImpact = cvssConfidentialityImpact; -318 } -319 /** -320 * CVSS Integrity Impact. -321 */ -322 private String cvssIntegrityImpact; -323 -324 /** -325 * Get the value of cvssIntegrityImpact. -326 * -327 * @return the value of cvssIntegrityImpact -328 */ -329 public String getCvssIntegrityImpact() { -330 return cvssIntegrityImpact; -331 } -332 -333 /** -334 * Set the value of cvssIntegrityImpact. -335 * -336 * @param cvssIntegrityImpact new value of cvssIntegrityImpact -337 */ -338 public void setCvssIntegrityImpact(String cvssIntegrityImpact) { -339 this.cvssIntegrityImpact = cvssIntegrityImpact; -340 } -341 /** -342 * CVSS Availability Impact. -343 */ -344 private String cvssAvailabilityImpact; -345 -346 /** -347 * Get the value of cvssAvailabilityImpact. -348 * -349 * @return the value of cvssAvailabilityImpact -350 */ -351 public String getCvssAvailabilityImpact() { -352 return cvssAvailabilityImpact; -353 } -354 -355 /** -356 * Set the value of cvssAvailabilityImpact. -357 * -358 * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact -359 */ -360 public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) { -361 this.cvssAvailabilityImpact = cvssAvailabilityImpact; -362 } -363 -364 @Override -365 public boolean equals(Object obj) { -366 if (obj == null) { -367 return false; -368 } -369 if (getClass() != obj.getClass()) { -370 return false; -371 } -372 final Vulnerability other = (Vulnerability) obj; -373 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { -374 return false; -375 } -376 return true; -377 } -378 -379 @Override -380 public int hashCode() { -381 int hash = 5; -382 hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0); -383 return hash; -384 } -385 -386 /** -387 * Compares two vulnerabilities. -388 * -389 * @param v a vulnerability to be compared -390 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than -391 * the specified vulnerability -392 */ -393 @Override -394 public int compareTo(Vulnerability v) { -395 return v.getName().compareTo(this.getName()); -396 } -397 -398 /** -399 * The CPE id that caused this vulnerability to be flagged. -400 */ -401 private String matchedCPE; -402 /** -403 * Whether or not all previous versions were affected. -404 */ -405 private String matchedAllPreviousCPE; -406 -407 /** -408 * Sets the CPE that caused this vulnerability to be flagged. -409 * -410 * @param cpeId a CPE identifier -411 * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is -412 * considered true) -413 */ -414 public void setMatchedCPE(String cpeId, String previous) { -415 matchedCPE = cpeId; -416 matchedAllPreviousCPE = previous; -417 } -418 -419 /** -420 * Get the value of matchedCPE. -421 * -422 * @return the value of matchedCPE -423 */ -424 public String getMatchedCPE() { -425 return matchedCPE; -426 } -427 -428 /** -429 * Get the value of matchedAllPreviousCPE. -430 * -431 * @return the value of matchedAllPreviousCPE -432 */ -433 public String getMatchedAllPreviousCPE() { -434 return matchedAllPreviousCPE; -435 } -436 -437 /** -438 * Determines whether or not matchedAllPreviousCPE has been set. -439 * -440 * @return true if matchedAllPreviousCPE is not null; otherwise false -441 */ -442 public boolean hasMatchedAllPreviousCPE() { -443 return matchedAllPreviousCPE != null; -444 } -445 } +24 import java.util.Iterator; +25 +26 /** +27 * Contains the information about a vulnerability. +28 * +29 * @author Jeremy Long +30 */ +31 public class Vulnerability implements Serializable, Comparable<Vulnerability> { +32 +33 /** +34 * The serial version uid. +35 */ +36 private static final long serialVersionUID = 307319490326651052L; +37 +38 /** +39 * The name of the vulnerability. +40 */ +41 private String name; +42 +43 /** +44 * Get the value of name. +45 * +46 * @return the value of name +47 */ +48 public String getName() { +49 return name; +50 } +51 +52 /** +53 * Set the value of name. +54 * +55 * @param name new value of name +56 */ +57 public void setName(String name) { +58 this.name = name; +59 } +60 /** +61 * the description of the vulnerability. +62 */ +63 private String description; +64 +65 /** +66 * Get the value of description. +67 * +68 * @return the value of description +69 */ +70 public String getDescription() { +71 return description; +72 } +73 +74 /** +75 * Set the value of description. +76 * +77 * @param description new value of description +78 */ +79 public void setDescription(String description) { +80 this.description = description; +81 } +82 /** +83 * References for this vulnerability. +84 */ +85 private SortedSet<Reference> references = new TreeSet<Reference>(); +86 +87 /** +88 * Get the value of references. +89 * +90 * @return the value of references +91 */ +92 public Set<Reference> getReferences() { +93 return references; +94 } +95 +96 /** +97 * Set the value of references. +98 * +99 * @param references new value of references +100 */ +101 public void setReferences(SortedSet<Reference> references) { +102 this.references = references; +103 } +104 +105 /** +106 * Adds a reference to the references collection. +107 * +108 * @param ref a reference for the vulnerability +109 */ +110 public void addReference(Reference ref) { +111 this.references.add(ref); +112 } +113 +114 /** +115 * Adds a reference. +116 * +117 * @param referenceSource the source of the reference +118 * @param referenceName the referenceName of the reference +119 * @param referenceUrl the url of the reference +120 */ +121 public void addReference(String referenceSource, String referenceName, String referenceUrl) { +122 final Reference ref = new Reference(); +123 ref.setSource(referenceSource); +124 ref.setName(referenceName); +125 ref.setUrl(referenceUrl); +126 this.references.add(ref); +127 } +128 /** +129 * A set of vulnerable software. +130 */ +131 private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>(); +132 +133 /** +134 * Get the value of vulnerableSoftware. +135 * +136 * @return the value of vulnerableSoftware +137 */ +138 public Set<VulnerableSoftware> getVulnerableSoftware() { +139 return vulnerableSoftware; +140 } +141 +142 /** +143 * Set the value of vulnerableSoftware. +144 * +145 * @param vulnerableSoftware new value of vulnerableSoftware +146 */ +147 public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) { +148 this.vulnerableSoftware = vulnerableSoftware; +149 } +150 +151 /** +152 * Adds an entry for vulnerable software. +153 * +154 * @param cpe string representation of a CPE entry +155 * @return if the add succeeded +156 */ +157 public boolean addVulnerableSoftware(String cpe) { +158 return addVulnerableSoftware(cpe, null); +159 } +160 +161 /** +162 * Adds an entry for vulnerable software. +163 * +164 * @param cpe string representation of a cpe +165 * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable) +166 * @return if the add succeeded +167 */ +168 public boolean addVulnerableSoftware(String cpe, String previousVersion) { +169 final VulnerableSoftware vs = new VulnerableSoftware(); +170 vs.setCpe(cpe); +171 if (previousVersion != null) { +172 vs.setPreviousVersion(previousVersion); +173 } +174 return updateVulnerableSoftware(vs); +175 } +176 +177 /** +178 * Adds or updates a vulnerable software entry. +179 * +180 * @param vulnSoftware the vulnerable software +181 * @return if the update succeeded +182 */ +183 public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) { +184 if (vulnerableSoftware.contains(vulnSoftware)) { +185 vulnerableSoftware.remove(vulnSoftware); +186 } +187 return vulnerableSoftware.add(vulnSoftware); +188 } +189 /** +190 * The CWE for the vulnerability. +191 */ +192 private String cwe; +193 +194 /** +195 * Get the value of cwe. +196 * +197 * @return the value of cwe +198 */ +199 public String getCwe() { +200 return cwe; +201 } +202 +203 /** +204 * Set the value of cwe. +205 * +206 * @param cwe new value of cwe +207 */ +208 public void setCwe(String cwe) { +209 this.cwe = cwe; +210 } +211 /** +212 * CVSS Score. +213 */ +214 private float cvssScore; +215 +216 /** +217 * Get the value of cvssScore. +218 * +219 * @return the value of cvssScore +220 */ +221 public float getCvssScore() { +222 return cvssScore; +223 } +224 +225 /** +226 * Set the value of cvssScore. +227 * +228 * @param cvssScore new value of cvssScore +229 */ +230 public void setCvssScore(float cvssScore) { +231 this.cvssScore = cvssScore; +232 } +233 /** +234 * CVSS Access Vector. +235 */ +236 private String cvssAccessVector; +237 +238 /** +239 * Get the value of cvssAccessVector. +240 * +241 * @return the value of cvssAccessVector +242 */ +243 public String getCvssAccessVector() { +244 return cvssAccessVector; +245 } +246 +247 /** +248 * Set the value of cvssAccessVector. +249 * +250 * @param cvssAccessVector new value of cvssAccessVector +251 */ +252 public void setCvssAccessVector(String cvssAccessVector) { +253 this.cvssAccessVector = cvssAccessVector; +254 } +255 /** +256 * CVSS Access Complexity. +257 */ +258 private String cvssAccessComplexity; +259 +260 /** +261 * Get the value of cvssAccessComplexity. +262 * +263 * @return the value of cvssAccessComplexity +264 */ +265 public String getCvssAccessComplexity() { +266 return cvssAccessComplexity; +267 } +268 +269 /** +270 * Set the value of cvssAccessComplexity. +271 * +272 * @param cvssAccessComplexity new value of cvssAccessComplexity +273 */ +274 public void setCvssAccessComplexity(String cvssAccessComplexity) { +275 this.cvssAccessComplexity = cvssAccessComplexity; +276 } +277 /** +278 * CVSS Authentication. +279 */ +280 private String cvssAuthentication; +281 +282 /** +283 * Get the value of cvssAuthentication. +284 * +285 * @return the value of cvssAuthentication +286 */ +287 public String getCvssAuthentication() { +288 return cvssAuthentication; +289 } +290 +291 /** +292 * Set the value of cvssAuthentication. +293 * +294 * @param cvssAuthentication new value of cvssAuthentication +295 */ +296 public void setCvssAuthentication(String cvssAuthentication) { +297 this.cvssAuthentication = cvssAuthentication; +298 } +299 /** +300 * CVSS Confidentiality Impact. +301 */ +302 private String cvssConfidentialityImpact; +303 +304 /** +305 * Get the value of cvssConfidentialityImpact. +306 * +307 * @return the value of cvssConfidentialityImpact +308 */ +309 public String getCvssConfidentialityImpact() { +310 return cvssConfidentialityImpact; +311 } +312 +313 /** +314 * Set the value of cvssConfidentialityImpact. +315 * +316 * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact +317 */ +318 public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) { +319 this.cvssConfidentialityImpact = cvssConfidentialityImpact; +320 } +321 /** +322 * CVSS Integrity Impact. +323 */ +324 private String cvssIntegrityImpact; +325 +326 /** +327 * Get the value of cvssIntegrityImpact. +328 * +329 * @return the value of cvssIntegrityImpact +330 */ +331 public String getCvssIntegrityImpact() { +332 return cvssIntegrityImpact; +333 } +334 +335 /** +336 * Set the value of cvssIntegrityImpact. +337 * +338 * @param cvssIntegrityImpact new value of cvssIntegrityImpact +339 */ +340 public void setCvssIntegrityImpact(String cvssIntegrityImpact) { +341 this.cvssIntegrityImpact = cvssIntegrityImpact; +342 } +343 /** +344 * CVSS Availability Impact. +345 */ +346 private String cvssAvailabilityImpact; +347 +348 /** +349 * Get the value of cvssAvailabilityImpact. +350 * +351 * @return the value of cvssAvailabilityImpact +352 */ +353 public String getCvssAvailabilityImpact() { +354 return cvssAvailabilityImpact; +355 } +356 +357 /** +358 * Set the value of cvssAvailabilityImpact. +359 * +360 * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact +361 */ +362 public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) { +363 this.cvssAvailabilityImpact = cvssAvailabilityImpact; +364 } +365 +366 @Override +367 public boolean equals(Object obj) { +368 if (obj == null) { +369 return false; +370 } +371 if (getClass() != obj.getClass()) { +372 return false; +373 } +374 final Vulnerability other = (Vulnerability) obj; +375 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { +376 return false; +377 } +378 return true; +379 } +380 +381 @Override +382 public int hashCode() { +383 int hash = 5; +384 hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0); +385 return hash; +386 } +387 +388 @Override +389 public String toString() { +390 final StringBuilder sb = new StringBuilder("Vulnerability "); +391 sb.append(this.name); +392 sb.append("\nReferences:\n"); +393 for (Iterator i = this.references.iterator(); i.hasNext();) { +394 sb.append("=> "); +395 sb.append(i.next()); +396 sb.append("\n"); +397 } +398 sb.append("\nSoftware:\n"); +399 for (Iterator i = this.vulnerableSoftware.iterator(); i.hasNext();) { +400 sb.append("=> "); +401 sb.append(i.next()); +402 sb.append("\n"); +403 } +404 return sb.toString(); +405 } +406 /** +407 * Compares two vulnerabilities. +408 * +409 * @param v a vulnerability to be compared +410 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than +411 * the specified vulnerability +412 */ +413 @Override +414 public int compareTo(Vulnerability v) { +415 return v.getName().compareTo(this.getName()); +416 } +417 +418 /** +419 * The CPE id that caused this vulnerability to be flagged. +420 */ +421 private String matchedCPE; +422 /** +423 * Whether or not all previous versions were affected. +424 */ +425 private String matchedAllPreviousCPE; +426 +427 /** +428 * Sets the CPE that caused this vulnerability to be flagged. +429 * +430 * @param cpeId a CPE identifier +431 * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is +432 * considered true) +433 */ +434 public void setMatchedCPE(String cpeId, String previous) { +435 matchedCPE = cpeId; +436 matchedAllPreviousCPE = previous; +437 } +438 +439 /** +440 * Get the value of matchedCPE. +441 * +442 * @return the value of matchedCPE +443 */ +444 public String getMatchedCPE() { +445 return matchedCPE; +446 } +447 +448 /** +449 * Get the value of matchedAllPreviousCPE. +450 * +451 * @return the value of matchedAllPreviousCPE +452 */ +453 public String getMatchedAllPreviousCPE() { +454 return matchedAllPreviousCPE; +455 } +456 +457 /** +458 * Determines whether or not matchedAllPreviousCPE has been set. +459 * +460 * @return true if matchedAllPreviousCPE is not null; otherwise false +461 */ +462 public boolean hasMatchedAllPreviousCPE() { +463 return matchedAllPreviousCPE != null; +464 } +465 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html index d65afcba3..70070a957 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html @@ -146,7 +146,7 @@ 138 return false; 139 } 140 final VulnerableSoftware other = (VulnerableSoftware) obj; -141 if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) { +141 if ((this.name == null) ? (other.getName() != null) : !this.name.equals(other.getName())) { 142 return false; 143 } 144 return true; @@ -160,7 +160,7 @@ 152 @Override 153 public int hashCode() { 154 int hash = 7; -155 hash = 83 * hash + (this.getName() != null ? this.getName().hashCode() : 0); +155 hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0); 156 return hash; 157 } 158 @@ -171,7 +171,7 @@ 163 */ 164 @Override 165 public String toString() { -166 return "VulnerableSoftware{ name=" + name + ", previousVersion=" + previousVersion + '}'; +166 return "VulnerableSoftware{" + name + "[" + previousVersion + "]}"; 167 } 168 169 /** @@ -183,203 +183,194 @@ 175 @Override 176 public int compareTo(VulnerableSoftware vs) { 177 int result = 0; -178 final String[] left = this.getName().split(":"); +178 final String[] left = this.name.split(":"); 179 final String[] right = vs.getName().split(":"); 180 final int max = (left.length <= right.length) ? left.length : right.length; 181 if (max > 0) { 182 for (int i = 0; result == 0 && i < max; i++) { -183 final String[] subLeft = left[i].split("\\."); -184 final String[] subRight = right[i].split("\\."); +183 final String[] subLeft = left[i].split("(\\.|-)"); +184 final String[] subRight = right[i].split("(\\.|-)"); 185 final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length; 186 if (subMax > 0) { 187 for (int x = 0; result == 0 && x < subMax; x++) { 188 if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) { 189 try { 190 result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x])); -191 // final long iLeft = Long.parseLong(subLeft[x]); -192 // final long iRight = Long.parseLong(subRight[x]); -193 // if (iLeft != iRight) { -194 // if (iLeft > iRight) { -195 // result = 2; -196 // } else { -197 // result = -2; -198 // } -199 // } -200 } catch (NumberFormatException ex) { -201 //ignore the exception - they obviously aren't numbers -202 if (!subLeft[x].equalsIgnoreCase(subRight[x])) { -203 result = subLeft[x].compareToIgnoreCase(subRight[x]); -204 } -205 } -206 } else { -207 result = subLeft[x].compareToIgnoreCase(subRight[x]); -208 } -209 } -210 if (result == 0) { -211 if (subLeft.length > subRight.length) { -212 result = 2; -213 } -214 if (subRight.length > subLeft.length) { -215 result = -2; -216 } -217 } -218 } else { -219 result = left[i].compareToIgnoreCase(right[i]); -220 } -221 } -222 if (result == 0) { -223 if (left.length > right.length) { -224 result = 2; -225 } -226 if (right.length > left.length) { -227 result = -2; -228 } -229 } -230 } else { -231 result = this.getName().compareToIgnoreCase(vs.getName()); -232 } -233 return result; -234 } -235 -236 /** -237 * Determines if the string passed in is a positive integer. -238 * -239 * @param str the string to test -240 * @return true if the string only contains 0-9, otherwise false. -241 */ -242 private static boolean isPositiveInteger(final String str) { -243 if (str == null || str.isEmpty()) { -244 return false; -245 } -246 for (int i = 0; i < str.length(); i++) { -247 final char c = str.charAt(i); -248 if (c < '0' || c > '9') { -249 return false; -250 } -251 } -252 return true; -253 } -254 /** -255 * The name of the cpe. -256 */ -257 private String name; +191 } catch (NumberFormatException ex) { +192 //ignore the exception - they obviously aren't numbers +193 if (!subLeft[x].equalsIgnoreCase(subRight[x])) { +194 result = subLeft[x].compareToIgnoreCase(subRight[x]); +195 } +196 } +197 } else { +198 result = subLeft[x].compareToIgnoreCase(subRight[x]); +199 } +200 } +201 if (result == 0) { +202 if (subLeft.length > subRight.length) { +203 result = 2; +204 } +205 if (subRight.length > subLeft.length) { +206 result = -2; +207 } +208 } +209 } else { +210 result = left[i].compareToIgnoreCase(right[i]); +211 } +212 } +213 if (result == 0) { +214 if (left.length > right.length) { +215 result = 2; +216 } +217 if (right.length > left.length) { +218 result = -2; +219 } +220 } +221 } else { +222 result = this.getName().compareToIgnoreCase(vs.getName()); +223 } +224 return result; +225 } +226 +227 /** +228 * Determines if the string passed in is a positive integer. +229 * +230 * @param str the string to test +231 * @return true if the string only contains 0-9, otherwise false. +232 */ +233 private static boolean isPositiveInteger(final String str) { +234 if (str == null || str.isEmpty()) { +235 return false; +236 } +237 for (int i = 0; i < str.length(); i++) { +238 final char c = str.charAt(i); +239 if (c < '0' || c > '9') { +240 return false; +241 } +242 } +243 return true; +244 } +245 /** +246 * The name of the cpe. +247 */ +248 private String name; +249 +250 /** +251 * Get the value of name. +252 * +253 * @return the value of name +254 */ +255 public String getName() { +256 return name; +257 } 258 259 /** -260 * Get the value of name. +260 * Set the value of name. 261 * -262 * @return the value of name +262 * @param name new value of name 263 */ -264 public String getName() { -265 return name; +264 public void setName(String name) { +265 this.name = name; 266 } -267 -268 /** -269 * Set the value of name. -270 * -271 * @param name new value of name -272 */ -273 public void setName(String name) { -274 this.name = name; -275 } -276 /** -277 * The product version number. -278 */ -279 private String version; +267 /** +268 * The product version number. +269 */ +270 private String version; +271 +272 /** +273 * Get the value of version. +274 * +275 * @return the value of version +276 */ +277 public String getVersion() { +278 return version; +279 } 280 281 /** -282 * Get the value of version. +282 * Set the value of version. 283 * -284 * @return the value of version +284 * @param version new value of version 285 */ -286 public String getVersion() { -287 return version; +286 public void setVersion(String version) { +287 this.version = version; 288 } -289 -290 /** -291 * Set the value of version. -292 * -293 * @param version new value of version -294 */ -295 public void setVersion(String version) { -296 this.version = version; -297 } -298 /** -299 * The product update version. -300 */ -301 private String update; +289 /** +290 * The product update version. +291 */ +292 private String update; +293 +294 /** +295 * Get the value of update. +296 * +297 * @return the value of update +298 */ +299 public String getUpdate() { +300 return update; +301 } 302 303 /** -304 * Get the value of update. +304 * Set the value of update. 305 * -306 * @return the value of update +306 * @param update new value of update 307 */ -308 public String getUpdate() { -309 return update; +308 public void setUpdate(String update) { +309 this.update = update; 310 } -311 -312 /** -313 * Set the value of update. -314 * -315 * @param update new value of update -316 */ -317 public void setUpdate(String update) { -318 this.update = update; -319 } -320 /** -321 * The product edition. -322 */ -323 private String edition; +311 /** +312 * The product edition. +313 */ +314 private String edition; +315 +316 /** +317 * Get the value of edition. +318 * +319 * @return the value of edition +320 */ +321 public String getEdition() { +322 return edition; +323 } 324 325 /** -326 * Get the value of edition. +326 * Set the value of edition. 327 * -328 * @return the value of edition +328 * @param edition new value of edition 329 */ -330 public String getEdition() { -331 return edition; +330 public void setEdition(String edition) { +331 this.edition = edition; 332 } 333 334 /** -335 * Set the value of edition. +335 * Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default. 336 * -337 * @param edition new value of edition -338 */ -339 public void setEdition(String edition) { -340 this.edition = edition; -341 } -342 -343 /** -344 * Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default. -345 * -346 * @param string the string to URL Decode -347 * @return the URL Decoded string -348 */ -349 private String urlDecode(String string) { -350 final String text = string.replace("+", "%2B"); -351 String result; -352 try { -353 result = URLDecoder.decode(text, "UTF-8"); -354 } catch (UnsupportedEncodingException ex) { -355 try { -356 result = URLDecoder.decode(text, "ASCII"); -357 } catch (UnsupportedEncodingException ex1) { -358 result = defaultUrlDecode(text); -359 } -360 } -361 return result; -362 } -363 -364 /** -365 * Call {@link java.net.URLDecoder#decode(String)} to URL decode using the default encoding. -366 * -367 * @param text www-form-encoded URL to decode -368 * @return the newly decoded String -369 */ -370 @SuppressWarnings("deprecation") -371 private String defaultUrlDecode(final String text) { -372 return URLDecoder.decode(text); -373 } -374 } +337 * @param string the string to URL Decode +338 * @return the URL Decoded string +339 */ +340 private String urlDecode(String string) { +341 final String text = string.replace("+", "%2B"); +342 String result; +343 try { +344 result = URLDecoder.decode(text, "UTF-8"); +345 } catch (UnsupportedEncodingException ex) { +346 try { +347 result = URLDecoder.decode(text, "ASCII"); +348 } catch (UnsupportedEncodingException ex1) { +349 result = defaultUrlDecode(text); +350 } +351 } +352 return result; +353 } +354 +355 /** +356 * Call {@link java.net.URLDecoder#decode(String)} to URL decode using the default encoding. +357 * +358 * @param text www-form-encoded URL to decode +359 * @return the newly decoded String +360 */ +361 @SuppressWarnings("deprecation") +362 private String defaultUrlDecode(final String text) { +363 return URLDecoder.decode(text); +364 } +365 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-frame.html index f5ebb248b..1490db258 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.dependency diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-summary.html index e1c65c505..3bce3140f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.dependency diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-frame.html index fce19b696..3f6e4600c 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.exception + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-summary.html index 34134ccea..176a78488 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.exception + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/package-frame.html index f08868051..978b33701 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/package-summary.html index d706b2c2e..1e4b7f82d 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/package-frame.html index 66dc070e4..758ac9748 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.reporting diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/package-summary.html index 6d1fc5cfc..90205f3ea 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.reporting diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html b/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html index 506607034..366d09df7 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html @@ -55,87 +55,155 @@ 47 */ 48 private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class); 49 /** -50 * JAXP Schema Language. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html -51 */ -52 public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; -53 /** -54 * W3C XML Schema. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html -55 */ -56 public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; -57 /** -58 * JAXP Schema Source. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html -59 */ -60 public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; -61 -62 /** -63 * Parses the given xml file and returns a list of the suppression rules contained. -64 * -65 * @param file an xml file containing suppression rules -66 * @return a list of suppression rules -67 * @throws SuppressionParseException thrown if the xml file cannot be parsed -68 */ -69 public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException { -70 FileInputStream fis = null; -71 try { -72 fis = new FileInputStream(file); -73 return parseSuppressionRules(fis); -74 } catch (IOException ex) { -75 LOGGER.debug("", ex); -76 throw new SuppressionParseException(ex); -77 } finally { -78 if (fis != null) { -79 try { -80 fis.close(); -81 } catch (IOException ex) { -82 LOGGER.debug("Unable to close stream", ex); -83 } -84 } -85 } -86 } -87 -88 /** -89 * Parses the given xml stream and returns a list of the suppression rules contained. -90 * -91 * @param inputStream an InputStream containing suppression rues -92 * @return a list of suppression rules -93 * @throws SuppressionParseException if the xml cannot be parsed -94 */ -95 public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException { -96 try { -97 final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd"); -98 final SuppressionHandler handler = new SuppressionHandler(); -99 final SAXParserFactory factory = SAXParserFactory.newInstance(); -100 factory.setNamespaceAware(true); -101 factory.setValidating(true); -102 final SAXParser saxParser = factory.newSAXParser(); -103 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); -104 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream)); -105 final XMLReader xmlReader = saxParser.getXMLReader(); -106 xmlReader.setErrorHandler(new SuppressionErrorHandler()); -107 xmlReader.setContentHandler(handler); -108 -109 final Reader reader = new InputStreamReader(inputStream, "UTF-8"); -110 final InputSource in = new InputSource(reader); -111 //in.setEncoding("UTF-8"); -112 -113 xmlReader.parse(in); -114 -115 return handler.getSuppressionRules(); -116 } catch (ParserConfigurationException ex) { -117 LOGGER.debug("", ex); -118 throw new SuppressionParseException(ex); -119 } catch (SAXException ex) { -120 LOGGER.debug("", ex); -121 throw new SuppressionParseException(ex); -122 } catch (FileNotFoundException ex) { -123 LOGGER.debug("", ex); -124 throw new SuppressionParseException(ex); -125 } catch (IOException ex) { -126 LOGGER.debug("", ex); -127 throw new SuppressionParseException(ex); -128 } -129 } -130 } +50 * JAXP Schema Language. Source: +51 * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html +52 */ +53 public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; +54 /** +55 * W3C XML Schema. Source: +56 * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html +57 */ +58 public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; +59 /** +60 * JAXP Schema Source. Source: +61 * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html +62 */ +63 public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; +64 +65 /** +66 * Parses the given xml file and returns a list of the suppression rules +67 * contained. +68 * +69 * @param file an xml file containing suppression rules +70 * @return a list of suppression rules +71 * @throws SuppressionParseException thrown if the xml file cannot be parsed +72 */ +73 public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException { +74 FileInputStream fis = null; +75 try { +76 fis = new FileInputStream(file); +77 return parseSuppressionRules(fis); +78 } catch (IOException ex) { +79 LOGGER.debug("", ex); +80 throw new SuppressionParseException(ex); +81 } catch (SAXException ex) { +82 try { +83 if (fis != null) { +84 try { +85 fis.close(); +86 } catch (IOException ex1) { +87 LOGGER.debug("Unable to close stream", ex1); +88 } +89 } +90 fis = new FileInputStream(file); +91 } catch (FileNotFoundException ex1) { +92 throw new SuppressionParseException(ex); +93 } +94 return parseOldSuppressionRules(fis); +95 } finally { +96 if (fis != null) { +97 try { +98 fis.close(); +99 } catch (IOException ex) { +100 LOGGER.debug("Unable to close stream", ex); +101 } +102 } +103 } +104 } +105 +106 /** +107 * Parses the given xml stream and returns a list of the suppression rules +108 * contained. +109 * +110 * @param inputStream an InputStream containing suppression rues +111 * @return a list of suppression rules +112 * @throws SuppressionParseException thrown if the xml cannot be parsed +113 * @throws SAXException thrown if the xml cannot be parsed +114 */ +115 public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException { +116 try { +117 final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/dependency-suppression.1.1.xsd"); +118 final SuppressionHandler handler = new SuppressionHandler(); +119 final SAXParserFactory factory = SAXParserFactory.newInstance(); +120 factory.setNamespaceAware(true); +121 factory.setValidating(true); +122 final SAXParser saxParser = factory.newSAXParser(); +123 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); +124 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream)); +125 final XMLReader xmlReader = saxParser.getXMLReader(); +126 xmlReader.setErrorHandler(new SuppressionErrorHandler()); +127 xmlReader.setContentHandler(handler); +128 +129 final Reader reader = new InputStreamReader(inputStream, "UTF-8"); +130 final InputSource in = new InputSource(reader); +131 //in.setEncoding("UTF-8"); +132 +133 xmlReader.parse(in); +134 +135 return handler.getSuppressionRules(); +136 } catch (ParserConfigurationException ex) { +137 LOGGER.debug("", ex); +138 throw new SuppressionParseException(ex); +139 } catch (SAXException ex) { +140 if (ex.getMessage().contains("Cannot find the declaration of element 'suppressions'.")) { +141 throw ex; +142 } else { +143 LOGGER.debug("", ex); +144 throw new SuppressionParseException(ex); +145 } +146 } catch (FileNotFoundException ex) { +147 LOGGER.debug("", ex); +148 throw new SuppressionParseException(ex); +149 } catch (IOException ex) { +150 LOGGER.debug("", ex); +151 throw new SuppressionParseException(ex); +152 } +153 } +154 +155 /** +156 * Parses the given xml stream and returns a list of the suppression rules +157 * contained. +158 * +159 * @param inputStream an InputStream containing suppression rues +160 * @return a list of suppression rules +161 * @throws SuppressionParseException if the xml cannot be parsed +162 */ +163 private List<SuppressionRule> parseOldSuppressionRules(InputStream inputStream) throws SuppressionParseException { +164 try { +165 final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd"); +166 final SuppressionHandler handler = new SuppressionHandler(); +167 final SAXParserFactory factory = SAXParserFactory.newInstance(); +168 factory.setNamespaceAware(true); +169 factory.setValidating(true); +170 final SAXParser saxParser = factory.newSAXParser(); +171 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); +172 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream)); +173 final XMLReader xmlReader = saxParser.getXMLReader(); +174 xmlReader.setErrorHandler(new SuppressionErrorHandler()); +175 xmlReader.setContentHandler(handler); +176 +177 final Reader reader = new InputStreamReader(inputStream, "UTF-8"); +178 final InputSource in = new InputSource(reader); +179 //in.setEncoding("UTF-8"); +180 +181 xmlReader.parse(in); +182 +183 return handler.getSuppressionRules(); +184 } catch (ParserConfigurationException ex) { +185 LOGGER.debug("", ex); +186 throw new SuppressionParseException(ex); +187 } catch (SAXException ex) { +188 LOGGER.debug("", ex); +189 throw new SuppressionParseException(ex); +190 } catch (FileNotFoundException ex) { +191 LOGGER.debug("", ex); +192 throw new SuppressionParseException(ex); +193 } catch (IOException ex) { +194 LOGGER.debug("", ex); +195 throw new SuppressionParseException(ex); +196 } +197 } +198 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/suppression/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/suppression/package-frame.html index 6b66d9aea..540858801 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/suppression/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/suppression/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.suppression diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/suppression/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/suppression/package-summary.html index f3b719522..8bbdbf572 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/suppression/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/suppression/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.suppression diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/utils/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/utils/package-frame.html index 3205316e2..a888e9a31 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/utils/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/utils/package-summary.html index f18252cbb..d55cb0855 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/Model.html b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/Model.html index 902aa750d..ae086b16f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/Model.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/Model.html @@ -270,92 +270,120 @@ 262 } 263 264 /** -265 * Process the Maven properties file and interpolate all properties. -266 * -267 * @param properties new value of properties -268 */ -269 public void processProperties(Properties properties) { -270 this.groupId = interpolateString(this.groupId, properties); -271 this.artifactId = interpolateString(this.artifactId, properties); -272 this.version = interpolateString(this.version, properties); -273 this.description = interpolateString(this.description, properties); -274 for (License l : this.getLicenses()) { -275 l.setName(interpolateString(l.getName(), properties)); -276 l.setUrl(interpolateString(l.getUrl(), properties)); -277 } -278 this.name = interpolateString(this.name, properties); -279 this.organization = interpolateString(this.organization, properties); -280 this.parentGroupId = interpolateString(this.parentGroupId, properties); -281 this.parentArtifactId = interpolateString(this.parentArtifactId, properties); -282 this.parentVersion = interpolateString(this.parentVersion, properties); -283 -284 } -285 -286 /** -287 * <p> -288 * A utility function that will interpolate strings based on values given in the properties file. It will also interpolate the -289 * strings contained within the properties file so that properties can reference other properties.</p> -290 * <p> -291 * <b>Note:</b> if there is no property found the reference will be removed. In other words, if the interpolated string will -292 * be replaced with an empty string. -293 * </p> -294 * <p> -295 * Example:</p> -296 * <code> -297 * Properties p = new Properties(); -298 * p.setProperty("key", "value"); -299 * String s = interpolateString("'${key}' and '${nothing}'", p); -300 * System.out.println(s); -301 * </code> -302 * <p> -303 * Will result in:</p> -304 * <code> -305 * 'value' and '' -306 * </code> -307 * -308 * @param text the string that contains references to properties. -309 * @param properties a collection of properties that may be referenced within the text. -310 * @return the interpolated text. -311 */ -312 public static String interpolateString(String text, Properties properties) { -313 if (null == text || null == properties) { -314 return text; -315 } -316 final StrSubstitutor substitutor = new StrSubstitutor(new PropertyLookup(properties)); -317 return substitutor.replace(text); -318 } -319 -320 /** -321 * Utility class that can provide values from a Properties object to a StrSubstitutor. -322 */ -323 private static class PropertyLookup extends StrLookup { -324 -325 /** -326 * Reference to the properties to lookup. -327 */ -328 private final Properties props; -329 -330 /** -331 * Constructs a new property lookup. -332 * -333 * @param props the properties to wrap. -334 */ -335 PropertyLookup(Properties props) { -336 this.props = props; -337 } -338 -339 /** -340 * Looks up the given property. -341 * -342 * @param key the key to the property -343 * @return the value of the property specified by the key -344 */ -345 @Override -346 public String lookup(String key) { -347 return props.getProperty(key); -348 } -349 } -350 } +265 * The project URL. +266 */ +267 private String projectURL; +268 +269 /** +270 * Get the value of projectURL. +271 * +272 * @return the value of projectURL +273 */ +274 public String getProjectURL() { +275 return projectURL; +276 } +277 +278 /** +279 * Set the value of projectURL. +280 * +281 * @param projectURL new value of projectURL +282 */ +283 public void setProjectURL(String projectURL) { +284 this.projectURL = projectURL; +285 } +286 +287 /** +288 * Process the Maven properties file and interpolate all properties. +289 * +290 * @param properties new value of properties +291 */ +292 public void processProperties(Properties properties) { +293 this.groupId = interpolateString(this.groupId, properties); +294 this.artifactId = interpolateString(this.artifactId, properties); +295 this.version = interpolateString(this.version, properties); +296 this.description = interpolateString(this.description, properties); +297 for (License l : this.getLicenses()) { +298 l.setName(interpolateString(l.getName(), properties)); +299 l.setUrl(interpolateString(l.getUrl(), properties)); +300 } +301 this.name = interpolateString(this.name, properties); +302 this.projectURL = interpolateString(this.projectURL, properties); +303 this.organization = interpolateString(this.organization, properties); +304 this.parentGroupId = interpolateString(this.parentGroupId, properties); +305 this.parentArtifactId = interpolateString(this.parentArtifactId, properties); +306 this.parentVersion = interpolateString(this.parentVersion, properties); +307 } +308 +309 /** +310 * <p> +311 * A utility function that will interpolate strings based on values given in +312 * the properties file. It will also interpolate the strings contained +313 * within the properties file so that properties can reference other +314 * properties.</p> +315 * <p> +316 * <b>Note:</b> if there is no property found the reference will be removed. +317 * In other words, if the interpolated string will be replaced with an empty +318 * string. +319 * </p> +320 * <p> +321 * Example:</p> +322 * <code> +323 * Properties p = new Properties(); +324 * p.setProperty("key", "value"); +325 * String s = interpolateString("'${key}' and '${nothing}'", p); +326 * System.out.println(s); +327 * </code> +328 * <p> +329 * Will result in:</p> +330 * <code> +331 * 'value' and '' +332 * </code> +333 * +334 * @param text the string that contains references to properties. +335 * @param properties a collection of properties that may be referenced +336 * within the text. +337 * @return the interpolated text. +338 */ +339 public static String interpolateString(String text, Properties properties) { +340 if (null == text || null == properties) { +341 return text; +342 } +343 final StrSubstitutor substitutor = new StrSubstitutor(new PropertyLookup(properties)); +344 return substitutor.replace(text); +345 } +346 +347 /** +348 * Utility class that can provide values from a Properties object to a +349 * StrSubstitutor. +350 */ +351 private static class PropertyLookup extends StrLookup { +352 +353 /** +354 * Reference to the properties to lookup. +355 */ +356 private final Properties props; +357 +358 /** +359 * Constructs a new property lookup. +360 * +361 * @param props the properties to wrap. +362 */ +363 PropertyLookup(Properties props) { +364 this.props = props; +365 } +366 +367 /** +368 * Looks up the given property. +369 * +370 * @param key the key to the property +371 * @return the value of the property specified by the key +372 */ +373 @Override +374 public String lookup(String key) { +375 return props.getProperty(key); +376 } +377 } +378 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomHandler.html b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomHandler.html index cc7ac93dc..826c65500 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomHandler.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomHandler.html @@ -153,49 +153,51 @@ 145 model.setOrganization(currentText.toString()); 146 } else if (DESCRIPTION.equals(qName)) { 147 model.setDescription(currentText.toString()); -148 } -149 } else if (PARENT.equals(parentNode)) { -150 if (GROUPID.equals(qName)) { -151 model.setParentGroupId(currentText.toString()); -152 } else if (ARTIFACTID.equals(qName)) { -153 model.setParentArtifactId(currentText.toString()); -154 } else if (VERSION.equals(qName)) { -155 model.setParentVersion(currentText.toString()); -156 } -157 } else if (LICENSE.equals(parentNode)) { -158 if (license != null) { -159 if (NAME.equals(qName)) { -160 license.setName(currentText.toString()); -161 } else if (URL.equals(qName)) { -162 license.setUrl(currentText.toString()); -163 } -164 //} else { -165 //TODO add error logging -166 } -167 } else if (LICENSES.equals(parentNode)) { -168 if (LICENSE.equals(qName)) { -169 if (license != null) { -170 model.addLicense(license); -171 //} else { -172 //TODO add error logging -173 } -174 } -175 } -176 } -177 -178 /** -179 * Collects the body text of the node being processed. -180 * -181 * @param ch the char array of text -182 * @param start the start position to copy text from in the char array -183 * @param length the number of characters to copy from the char array -184 * @throws SAXException thrown if there is a parsing exception -185 */ -186 @Override -187 public void characters(char[] ch, int start, int length) throws SAXException { -188 currentText.append(ch, start, length); -189 } -190 } +148 } else if (URL.equals(qName)) { +149 model.setProjectURL(currentText.toString()); +150 } +151 } else if (PARENT.equals(parentNode)) { +152 if (GROUPID.equals(qName)) { +153 model.setParentGroupId(currentText.toString()); +154 } else if (ARTIFACTID.equals(qName)) { +155 model.setParentArtifactId(currentText.toString()); +156 } else if (VERSION.equals(qName)) { +157 model.setParentVersion(currentText.toString()); +158 } +159 } else if (LICENSE.equals(parentNode)) { +160 if (license != null) { +161 if (NAME.equals(qName)) { +162 license.setName(currentText.toString()); +163 } else if (URL.equals(qName)) { +164 license.setUrl(currentText.toString()); +165 } +166 //} else { +167 //TODO add error logging +168 } +169 } else if (LICENSES.equals(parentNode)) { +170 if (LICENSE.equals(qName)) { +171 if (license != null) { +172 model.addLicense(license); +173 //} else { +174 //TODO add error logging +175 } +176 } +177 } +178 } +179 +180 /** +181 * Collects the body text of the node being processed. +182 * +183 * @param ch the char array of text +184 * @param start the start position to copy text from in the char array +185 * @param length the number of characters to copy from the char array +186 * @throws SAXException thrown if there is a parsing exception +187 */ +188 @Override +189 public void characters(char[] ch, int start, int length) throws SAXException { +190 currentText.append(ch, start, length); +191 } +192 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/package-frame.html index 2efd6af86..aeaa91039 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/package-summary.html index 4dc26febb..5f3e82bde 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/dependency-check-core/xref/overview-frame.html b/dependency-check-core/xref/overview-frame.html index 21869e23f..963ad2cff 100644 --- a/dependency-check-core/xref/overview-frame.html +++ b/dependency-check-core/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference + Dependency-Check Core 1.4.0 Reference diff --git a/dependency-check-core/xref/overview-summary.html b/dependency-check-core/xref/overview-summary.html index aed179e8c..13d19e050 100644 --- a/dependency-check-core/xref/overview-summary.html +++ b/dependency-check-core/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.3.6 Reference + Dependency-Check Core 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Core 1.3.6 Reference

      +

      Dependency-Check Core 1.4.0 Reference

      diff --git a/dependency-check-gradle/configuration-purge.html b/dependency-check-gradle/configuration-purge.html index 4bca014e3..17daea11b 100644 --- a/dependency-check-gradle/configuration-purge.html +++ b/dependency-check-gradle/configuration-purge.html @@ -1,15 +1,15 @@ - + - dependency-check-gradle – Tasks + dependency-check – Tasks @@ -41,7 +41,7 @@ diff --git a/dependency-check-gradle/configuration-update.html b/dependency-check-gradle/configuration-update.html index 11c3aac6f..3b635961f 100644 --- a/dependency-check-gradle/configuration-update.html +++ b/dependency-check-gradle/configuration-update.html @@ -1,15 +1,15 @@ - + - dependency-check-gradle – Tasks + dependency-check – Tasks @@ -41,7 +41,7 @@ diff --git a/dependency-check-gradle/configuration.html b/dependency-check-gradle/configuration.html index e3b0fe3c8..64210e4ca 100644 --- a/dependency-check-gradle/configuration.html +++ b/dependency-check-gradle/configuration.html @@ -1,15 +1,15 @@ - + - dependency-check-gradle – Tasks + dependency-check – Tasks @@ -41,7 +41,7 @@ @@ -373,7 +370,7 @@ - + @@ -587,6 +584,15 @@ + + + + + + + + + @@ -594,7 +600,7 @@ - + @@ -603,7 +609,7 @@ - + @@ -612,7 +618,7 @@ - + @@ -621,7 +627,7 @@ - + @@ -630,7 +636,7 @@ - + @@ -639,7 +645,7 @@ - + @@ -648,35 +654,35 @@ - + - - - - - - - - - - + - + - + + + + + + + + + + @@ -684,44 +690,44 @@ - + - + - + - - - - - - - - - - + - + - + + + + + + + + + + @@ -729,7 +735,7 @@ - + @@ -738,7 +744,7 @@ - + diff --git a/dependency-check-gradle/index.html b/dependency-check-gradle/index.html index fddab7999..0c4021624 100644 --- a/dependency-check-gradle/index.html +++ b/dependency-check-gradle/index.html @@ -1,15 +1,15 @@ - + - dependency-check-gradle – Usage + dependency-check – Usage @@ -41,7 +41,7 @@ @@ -239,7 +236,7 @@ mavenCentral() } dependencies { - classpath 'org.owasp:dependency-check-gradle:1.3.6' + classpath 'org.owasp:dependency-check-gradle:1.4.0' } } diff --git a/dependency-check-jenkins/index.html b/dependency-check-jenkins/index.html index 26b5c3447..df1b14352 100644 --- a/dependency-check-jenkins/index.html +++ b/dependency-check-jenkins/index.html @@ -1,13 +1,13 @@ - + dependency-check – Dependency-Check Jenkins Plugin @@ -41,7 +41,7 @@ diff --git a/dependency-check-maven/aggregate-mojo.html b/dependency-check-maven/aggregate-mojo.html index a3979c619..1180b61be 100644 --- a/dependency-check-maven/aggregate-mojo.html +++ b/dependency-check-maven/aggregate-mojo.html @@ -1,13 +1,13 @@ - + dependency-check-maven – dependency-check:aggregate @@ -52,7 +52,7 @@ @@ -138,9 +138,6 @@ developed using - - - built on cloudbees @@ -158,7 +155,7 @@

      Full name:

      -

      org.owasp:dependency-check-maven:1.3.6:aggregate

      +

      org.owasp:dependency-check-maven:1.4.0:aggregate

      Description:

      @@ -509,6 +506,17 @@ duration in hours.
      User property is: cveValidForHours. + + + + + + + + + + + @@ -518,7 +526,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -529,7 +537,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -540,7 +548,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -551,7 +559,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -562,7 +570,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -574,7 +582,7 @@ duration in hours.
      User property is: cveValidForHours. (http://domain/nexus/service/local).
      User property is: nexusUrl. - + @@ -585,7 +593,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -596,7 +604,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -607,7 +615,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -618,7 +626,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -629,7 +637,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -640,7 +648,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -651,7 +659,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -662,7 +670,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -673,7 +681,7 @@ duration in hours.
      User property is: cveValidForHours. - + @@ -685,7 +693,7 @@ duration in hours.
      User property is: cveValidForHours. passwords from the settings.xml.
      User property is: serverId. - + @@ -696,7 +704,7 @@ passwords from the settings.xml.
      User property is: serverId - + @@ -707,7 +715,7 @@ passwords from the settings.xml.
      User property is: serverId - + @@ -718,7 +726,7 @@ passwords from the settings.xml.
      User property is: serverId - + @@ -729,7 +737,7 @@ passwords from the settings.xml.
      User property is: serverId - + @@ -740,7 +748,7 @@ passwords from the settings.xml.
      User property is: serverId - + @@ -751,7 +759,7 @@ passwords from the settings.xml.
      User property is: serverId - + @@ -1027,6 +1035,18 @@ duration in hours.
    83. User Property: databaseUser

    84. +

      enableExperimental:

      + +
      Sets whether Experimental analyzers are enabled. Default is false.
      + +
        + +
      • Type: java.lang.Boolean
      • + +
      • Required: No
      • + +
      • User Property: enableExperimental
      • +

      externalReport:

      Deprecated. the internal report is no longer supported
      diff --git a/dependency-check-maven/apidocs/allclasses-frame.html b/dependency-check-maven/apidocs/allclasses-frame.html index ea9f0ab54..1eb15595b 100644 --- a/dependency-check-maven/apidocs/allclasses-frame.html +++ b/dependency-check-maven/apidocs/allclasses-frame.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Maven Plugin 1.3.6 API) - +All Classes (Dependency-Check Maven Plugin 1.4.0 API) + diff --git a/dependency-check-maven/apidocs/allclasses-noframe.html b/dependency-check-maven/apidocs/allclasses-noframe.html index 10a72f807..a2206e535 100644 --- a/dependency-check-maven/apidocs/allclasses-noframe.html +++ b/dependency-check-maven/apidocs/allclasses-noframe.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Maven Plugin 1.3.6 API) - +All Classes (Dependency-Check Maven Plugin 1.4.0 API) + diff --git a/dependency-check-maven/apidocs/constant-values.html b/dependency-check-maven/apidocs/constant-values.html index fd88ff15d..ad0c2de48 100644 --- a/dependency-check-maven/apidocs/constant-values.html +++ b/dependency-check-maven/apidocs/constant-values.html @@ -2,10 +2,10 @@ - + -Constant Field Values (Dependency-Check Maven Plugin 1.3.6 API) - +Constant Field Values (Dependency-Check Maven Plugin 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/package-summary.html b/dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/package-summary.html index 984f43297..17cf4bb7f 100644 --- a/dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/package-summary.html +++ b/dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.maven (Dependency-Check Maven Plugin 1.3.6 API) - +org.owasp.dependencycheck.maven (Dependency-Check Maven Plugin 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/package-summary.html b/dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/package-summary.html index 1e2bd8ea2..c8b03c078 100644 --- a/dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/package-summary.html +++ b/dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.maven.slf4j (Dependency-Check Maven Plugin 1.3.6 API) - +org.owasp.dependencycheck.maven.slf4j (Dependency-Check Maven Plugin 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-maven/apidocs/org/slf4j/impl/package-summary.html b/dependency-check-maven/apidocs/org/slf4j/impl/package-summary.html index 5f34073d9..942da3805 100644 --- a/dependency-check-maven/apidocs/org/slf4j/impl/package-summary.html +++ b/dependency-check-maven/apidocs/org/slf4j/impl/package-summary.html @@ -2,10 +2,10 @@ - + -org.slf4j.impl (Dependency-Check Maven Plugin 1.3.6 API) - +org.slf4j.impl (Dependency-Check Maven Plugin 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-maven/apidocs/overview-summary.html b/dependency-check-maven/apidocs/overview-summary.html index e44a1d787..23145483a 100644 --- a/dependency-check-maven/apidocs/overview-summary.html +++ b/dependency-check-maven/apidocs/overview-summary.html @@ -2,10 +2,10 @@ - + -Overview (Dependency-Check Maven Plugin 1.3.6 API) - +Overview (Dependency-Check Maven Plugin 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ - + diff --git a/dependency-check-maven/cobertura/frame-summary-org.owasp.dependencycheck.maven.slf4j.html b/dependency-check-maven/cobertura/frame-summary-org.owasp.dependencycheck.maven.slf4j.html index 7950e7794..0fb834faf 100644 --- a/dependency-check-maven/cobertura/frame-summary-org.owasp.dependencycheck.maven.slf4j.html +++ b/dependency-check-maven/cobertura/frame-summary-org.owasp.dependencycheck.maven.slf4j.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-maven/cobertura/frame-summary-org.slf4j.impl.html b/dependency-check-maven/cobertura/frame-summary-org.slf4j.impl.html index 8acaff248..3aee42d59 100644 --- a/dependency-check-maven/cobertura/frame-summary-org.slf4j.impl.html +++ b/dependency-check-maven/cobertura/frame-summary-org.slf4j.impl.html @@ -37,6 +37,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-maven/cobertura/frame-summary.html b/dependency-check-maven/cobertura/frame-summary.html index d29026f4a..54cb4ca04 100644 --- a/dependency-check-maven/cobertura/frame-summary.html +++ b/dependency-check-maven/cobertura/frame-summary.html @@ -16,8 +16,8 @@
      server The proxy server. The proxy server; see the proxy configuration page for more information.  
      experimentalEnabled Sets whether the experimental analyzers will be used. If not set to true the analyzers marked as experimental (see below) will not be used false
      archiveEnabled Sets whether the Archive Analyzer will be used. true
      zipExtensions  
      jarEnabled true
      centralEnabled true
      nexusEnabled true
      nexusUrl  
      nexusUsesProxy true
      pyDistributionEnabled Sets whether the Python Distribution Analyzer will be used. true
      pyPackageEnabled Sets whether the Python Package Analyzer will be used. Sets whether the experimental Python Distribution Analyzer will be used. true
      rubygemsEnabled pyPackageEnabled Sets whether the Ruby Gemspec Analyzer will be used. Sets whether the experimental Python Package Analyzer will be used. true
      rubygemsEnabled Sets whether the experimental Ruby Gemspec Analyzer will be used. true
      opensslEnabled Sets whether or not the openssl Analyzer should be used. true
      cmakeEnabled Sets whether or not the CMake Analyzer should be used. Sets whether or not the experimental CMake Analyzer should be used. true
      autoconfEnabled Sets whether or not the autoconf Analyzer should be used. true
      composerEnabled Sets whether or not the PHP Composer Lock File Analyzer should be used. Sets whether or not the experimental autoconf Analyzer should be used. true
      nodeEnabled composerEnabled Sets whether or not the Node.js Analyzer should be used. Sets whether or not the experimental PHP Composer Lock File Analyzer should be used. true
      nodeEnabled Sets whether or not the experimental Node.js Analyzer should be used. true
      nuspecEnabled Sets whether or not the .NET Nuget Nuspec Analyzer will be used. true
      assemblyEnabled true
      pathToMono
      enableExperimentalBoolean-Sets whether Experimental analyzers are enabled. Default is false.
      User property is: enableExperimental.
      externalReport String Deprecated. the internal report is no longer supported
      User property is: externalReport.
      jarAnalyzerEnabled Whether or not the Jar Analyzer is enabled.
      User property is: jarAnalyzerEnabled.
      mavenSettings The Maven settings.
      Default value is: ${settings}.
      User property is: mavenSettings.
      mavenSettingsProxyId The maven settings proxy id.
      User property is: mavenSettingsProxyId.
      nexusAnalyzerEnabled Whether or not the Nexus Analyzer is enabled.
      User property is: nexusAnalyzerEnabled.
      nexusUrl
      nexusUsesProxy Whether or not the configured proxy is used to connect to Nexus.
      User property is: nexusUsesProxy.
      nodeAnalyzerEnabled Sets whether or not the Node.js Analyzer should be used.
      User property is: nodeAnalyzerEnabled.
      nuspecAnalyzerEnabled Whether or not the .NET Nuspec Analyzer is enabled.
      User property is: nuspecAnalyzerEnabled.
      opensslAnalyzerEnabled Sets whether or not the openssl Analyzer should be used.
      User property is: opensslAnalyzerEnabled.
      pathToMono The path to mono for .NET Assembly analysis on non-windows systems.
      User property is: pathToMono.
      proxyUrl Deprecated. Please use mavenSettings instead
      User property is: proxyUrl.
      pyDistributionAnalyzerEnabled Sets whether the Python Distribution Analyzer will be used.
      User property is: pyDistributionAnalyzerEnabled.
      pyPackageAnalyzerEnabled Sets whether the Python Package Analyzer will be used.
      User property is: pyPackageAnalyzerEnabled.
      rubygemsAnalyzerEnabled Sets whether the Ruby Gemspec Analyzer will be used.
      User property is: rubygemsAnalyzerEnabled.
      serverId
      showSummary Flag indicating whether or not to show a summary in the output.
      Default value is: true.
      User property is: showSummary.
      skip Skip Dependency Check altogether.
      Default value is: false.
      User property is: dependency-check.skip.
      skipProvidedScope Skip Analysis for Provided Scope Dependencies.
      Default value is: false.
      User property is: skipProvidedScope.
      skipRuntimeScope Skip Analysis for Runtime Scope Dependencies.
      Default value is: false.
      User property is: skipRuntimeScope.
      skipTestScope Skip Analysis for Test Scope Dependencies.
      Default value is: true.
      User property is: skipTestScope.
      suppressionFile The path to the suppression file.
      User property is: suppressionFile.
      zipExtensions
      - - + + @@ -27,6 +27,6 @@ var packageTable = new SortableTable(document.getElementById("packageResults"), ["String", "Number", "Percentage", "Percentage", "FormattedNumber"]); packageTable.sort(0); - + diff --git a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.AggregateMojo.html b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.AggregateMojo.html index 2f0b1f6d6..537ecc672 100644 --- a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.AggregateMojo.html +++ b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.AggregateMojo.html @@ -535,6 +535,6 @@
      Package # Classes Line Coverage Branch Coverage Complexity
      All Packages10
      2%
      25/883
      0%
      3/494
      3.667
      org.owasp.dependencycheck.maven7
      0%
      0/728
      0%
      0/434
      4.506
      All Packages10
      2%
      25/884
      0%
      3/494
      3.667
      org.owasp.dependencycheck.maven7
      0%
      0/729
      0%
      0/434
      4.506
      org.owasp.dependencycheck.maven.slf4j2
      10%
      15/142
      5%
      3/60
      2.061
      org.slf4j.impl1
      76%
      10/13
      N/A
      1
       }
      - + diff --git a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.BaseDependencyCheckMojo.html b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.BaseDependencyCheckMojo.html index 392aabdc7..fc64ebb03 100644 --- a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.BaseDependencyCheckMojo.html +++ b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.BaseDependencyCheckMojo.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      BaseDependencyCheckMojo
      0%
      0/315
      0%
      0/162
      4.613
      BaseDependencyCheckMojo
      0%
      0/316
      0%
      0/162
      4.613
       
      @@ -208,613 +208,617 @@
       96  
           /**
       97  
            * Specifies the destination directory for the generated Dependency-Check report. This generally maps to "target/site".
            * Specifies the destination directory for the generated Dependency-Check
       98  
            */
            * report. This generally maps to "target/site".
       99  
           @Parameter(property = "project.reporting.outputDirectory", required = true)
            */
       100  
           private File reportOutputDirectory;
           @Parameter(property = "project.reporting.outputDirectory", required = true)
       101  
           /**
           private File reportOutputDirectory;
       102  
            * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which
           /**
       103  
            * means since the CVSS scores are 0-10, by default the build will never fail.
            * Specifies if the build should be failed if a CVSS score above a specified
       104  
            */
       105  0
           @SuppressWarnings("CanBeFinal")
            * level is identified. The default is 11 which means since the CVSS scores
       105  
            * are 0-10, by default the build will never fail.
       106  
           @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true)
       107  
           private float failBuildOnCVSS = 11;
       108  
           /**
       109  
            * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default
       110  
            * is true.
       111  
            */
       112  
           @SuppressWarnings("CanBeFinal")
       113  
           @Parameter(property = "autoUpdate")
       114  
           private Boolean autoUpdate;
       115  
       107  0
           @SuppressWarnings("CanBeFinal")
       108  
           @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true)
       109  
           private float failBuildOnCVSS = 11;
       110  
           /**
       111  
            * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
       112  
            * recommended that this be turned to false. Default is true.
       113  
            */
       114  
           @SuppressWarnings("CanBeFinal")
       115  
           @Parameter(property = "autoUpdate")
       116  
            * Generate aggregate reports in multi-module projects.
           private Boolean autoUpdate;
       117  
            *
           /**
       118  
            * @deprecated use the aggregate goal instead
            * Sets whether Experimental analyzers are enabled. Default is false.
       119  
            */
       120  
           @Parameter(property = "aggregate")
           @SuppressWarnings("CanBeFinal")
       121  
           @Deprecated
           @Parameter(property = "enableExperimental")
       122  
           private Boolean aggregate;
           private Boolean enableExperimental;
       123  
           /**
       124  
            * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the
            * Generate aggregate reports in multi-module projects.
       125  
            * Site plug-in unless the externalReport is set to true. Default is HTML.
            *
       126  
            * @deprecated use the aggregate goal instead
       127  
            */
       127  0
           @SuppressWarnings("CanBeFinal")
       128  
           @Parameter(property = "format", defaultValue = "HTML", required = true)
           @Parameter(property = "aggregate")
       129  
           private String format = "HTML";
           @Deprecated
       130  
           /**
           private Boolean aggregate;
       131  
            * The Maven settings.
           /**
       132  
            */
            * The report format to be generated (HTML, XML, VULN, ALL). This
       133  
           @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false)
            * configuration option has no affect if using this within the Site plug-in
       134  
           private org.apache.maven.settings.Settings mavenSettings;
            * unless the externalReport is set to true. Default is HTML.
       135  
       
       136  
           /**
            */
       136  0
           @SuppressWarnings("CanBeFinal")
       137  
            * The maven settings proxy id.
           @Parameter(property = "format", defaultValue = "HTML", required = true)
       138  
            */
           private String format = "HTML";
       139  
           @SuppressWarnings("CanBeFinal")
           /**
       140  
           @Parameter(property = "mavenSettingsProxyId", required = false)
            * The Maven settings.
       141  
           private String mavenSettingsProxyId;
            */
       142  
       
           @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false)
       143  
           /**
           private org.apache.maven.settings.Settings mavenSettings;
       144  
            * The Connection Timeout.
       
       145  
            */
           /**
       146  
           @Parameter(property = "connectionTimeout", defaultValue = "", required = false)
            * The maven settings proxy id.
       147  
           private String connectionTimeout;
            */
       148  
           /**
           @SuppressWarnings("CanBeFinal")
       149  
            * The path to the suppression file.
           @Parameter(property = "mavenSettingsProxyId", required = false)
       150  
            */
           private String mavenSettingsProxyId;
       151  
           @Parameter(property = "suppressionFile", defaultValue = "", required = false)
       
       152  
           private String suppressionFile;
           /**
       153  
           /**
            * The Connection Timeout.
       154  
            * Flag indicating whether or not to show a summary in the output.
            */
       155  
            */
       156  0
           @Parameter(property = "showSummary", defaultValue = "true", required = false)
           @Parameter(property = "connectionTimeout", defaultValue = "", required = false)
       156  
           private String connectionTimeout;
       157  
           private boolean showSummary = true;
           /**
       158  
       
            * The path to the suppression file.
       159  
           /**
            */
       160  
            * Whether or not the Jar Analyzer is enabled.
           @Parameter(property = "suppressionFile", defaultValue = "", required = false)
       161  
            */
           private String suppressionFile;
       162  
           @Parameter(property = "jarAnalyzerEnabled", required = false)
           /**
       163  
           private Boolean jarAnalyzerEnabled;
            * Flag indicating whether or not to show a summary in the output.
       164  
       
       165  
           /**
            */
       165  0
           @Parameter(property = "showSummary", defaultValue = "true", required = false)
       166  
            * Whether or not the Archive Analyzer is enabled.
           private boolean showSummary = true;
       167  
            */
       
       168  
           @Parameter(property = "archiveAnalyzerEnabled", required = false)
           /**
       169  
           private Boolean archiveAnalyzerEnabled;
            * Whether or not the Jar Analyzer is enabled.
       170  
       
            */
       171  
           /**
           @Parameter(property = "jarAnalyzerEnabled", required = false)
       172  
            * Sets whether the Python Distribution Analyzer will be used.
           private Boolean jarAnalyzerEnabled;
       173  
            */
       
       174  
           @Parameter(property = "pyDistributionAnalyzerEnabled", required = false)
           /**
       175  
           private Boolean pyDistributionAnalyzerEnabled;
            * Whether or not the Archive Analyzer is enabled.
       176  
           /**
            */
       177  
            * Sets whether the Python Package Analyzer will be used.
           @Parameter(property = "archiveAnalyzerEnabled", required = false)
       178  
            */
           private Boolean archiveAnalyzerEnabled;
       179  
           @Parameter(property = "pyPackageAnalyzerEnabled", required = false)
       
       180  
           private Boolean pyPackageAnalyzerEnabled;
           /**
       181  
           /**
            * Sets whether the Python Distribution Analyzer will be used.
       182  
            * Sets whether the Ruby Gemspec Analyzer will be used.
            */
       183  
            */
           @Parameter(property = "pyDistributionAnalyzerEnabled", required = false)
       184  
           @Parameter(property = "rubygemsAnalyzerEnabled", required = false)
           private Boolean pyDistributionAnalyzerEnabled;
       185  
           private Boolean rubygemsAnalyzerEnabled;
           /**
       186  
           /**
            * Sets whether the Python Package Analyzer will be used.
       187  
            * Sets whether or not the openssl Analyzer should be used.
            */
       188  
            */
           @Parameter(property = "pyPackageAnalyzerEnabled", required = false)
       189  
           @Parameter(property = "opensslAnalyzerEnabled", required = false)
           private Boolean pyPackageAnalyzerEnabled;
       190  
           private Boolean opensslAnalyzerEnabled;
           /**
       191  
           /**
            * Sets whether the Ruby Gemspec Analyzer will be used.
       192  
            * Sets whether or not the CMake Analyzer should be used.
            */
       193  
            */
           @Parameter(property = "rubygemsAnalyzerEnabled", required = false)
       194  
           @Parameter(property = "cmakeAnalyzerEnabled", required = false)
           private Boolean rubygemsAnalyzerEnabled;
       195  
           private Boolean cmakeAnalyzerEnabled;
           /**
       196  
           /**
            * Sets whether or not the openssl Analyzer should be used.
       197  
            * Sets whether or not the autoconf Analyzer should be used.
            */
       198  
            */
           @Parameter(property = "opensslAnalyzerEnabled", required = false)
       199  
           @Parameter(property = "autoconfAnalyzerEnabled", required = false)
           private Boolean opensslAnalyzerEnabled;
       200  
           private Boolean autoconfAnalyzerEnabled;
           /**
       201  
           /**
            * Sets whether or not the CMake Analyzer should be used.
       202  
            * Sets whether or not the PHP Composer Lock File Analyzer should be used.
            */
       203  
            */
           @Parameter(property = "cmakeAnalyzerEnabled", required = false)
       204  
           @Parameter(property = "composerAnalyzerEnabled", required = false)
           private Boolean cmakeAnalyzerEnabled;
       205  
           private Boolean composerAnalyzerEnabled;
           /**
       206  
           /**
            * Sets whether or not the autoconf Analyzer should be used.
       207  
            * Sets whether or not the Node.js Analyzer should be used.
            */
       208  
            */
           @Parameter(property = "autoconfAnalyzerEnabled", required = false)
       209  
           @Parameter(property = "nodeAnalyzerEnabled", required = false)
           private Boolean autoconfAnalyzerEnabled;
       210  
           private Boolean nodeAnalyzerEnabled;
           /**
       211  
       
            * Sets whether or not the PHP Composer Lock File Analyzer should be used.
       212  
           /**
            */
       213  
            * Whether or not the .NET Assembly Analyzer is enabled.
           @Parameter(property = "composerAnalyzerEnabled", required = false)
       214  
            */
           private Boolean composerAnalyzerEnabled;
       215  
           @Parameter(property = "assemblyAnalyzerEnabled", required = false)
           /**
       216  
           private Boolean assemblyAnalyzerEnabled;
            * Sets whether or not the Node.js Analyzer should be used.
       217  
       
            */
       218  
           /**
           @Parameter(property = "nodeAnalyzerEnabled", required = false)
       219  
            * Whether or not the .NET Nuspec Analyzer is enabled.
           private Boolean nodeAnalyzerEnabled;
       220  
            */
       
       221  
           @Parameter(property = "nuspecAnalyzerEnabled", required = false)
           /**
       222  
           private Boolean nuspecAnalyzerEnabled;
            * Whether or not the .NET Assembly Analyzer is enabled.
       223  
       
            */
       224  
           /**
           @Parameter(property = "assemblyAnalyzerEnabled", required = false)
       225  
            * Whether or not the Central Analyzer is enabled.
           private Boolean assemblyAnalyzerEnabled;
       226  
            */
       
       227  
           @Parameter(property = "centralAnalyzerEnabled", required = false)
           /**
       228  
           private Boolean centralAnalyzerEnabled;
            * Whether or not the .NET Nuspec Analyzer is enabled.
       229  
       
            */
       230  
           /**
           @Parameter(property = "nuspecAnalyzerEnabled", required = false)
       231  
            * Whether or not the Nexus Analyzer is enabled.
           private Boolean nuspecAnalyzerEnabled;
       232  
            */
       233  
           @Parameter(property = "nexusAnalyzerEnabled", required = false)
       234  
           private Boolean nexusAnalyzerEnabled;
       235  
       
       233  
           /**
       234  
            * Whether or not the Central Analyzer is enabled.
       235  
            */
       236  
           /**
           @Parameter(property = "centralAnalyzerEnabled", required = false)
       237  
            * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local).
           private Boolean centralAnalyzerEnabled;
       238  
            */
       
       239  
           @Parameter(property = "nexusUrl", required = false)
           /**
       240  
           private String nexusUrl;
            * Whether or not the Nexus Analyzer is enabled.
       241  
           /**
       242  
            * Whether or not the configured proxy is used to connect to Nexus.
       243  
            */
       242  
           @Parameter(property = "nexusAnalyzerEnabled", required = false)
       243  
           private Boolean nexusAnalyzerEnabled;
       244  
           @Parameter(property = "nexusUsesProxy", required = false)
       
       245  
           private Boolean nexusUsesProxy;
       246  
           /**
       246  
            * The URL of a Nexus server's REST API end point
       247  
            * The database connection string.
            * (http://domain/nexus/service/local).
       248  
            */
       249  
           @Parameter(property = "connectionString", defaultValue = "", required = false)
           @Parameter(property = "nexusUrl", required = false)
       250  
           private String connectionString;
           private String nexusUrl;
       251  
       
           /**
       252  
           /**
            * Whether or not the configured proxy is used to connect to Nexus.
       253  
            * Returns the connection string.
            */
       254  
            *
           @Parameter(property = "nexusUsesProxy", required = false)
       255  
            * @return the connection string
           private Boolean nexusUsesProxy;
       256  
            */
           /**
       257  
           protected String getConnectionString() {
       258  0
               return connectionString;
            * The database connection string.
       258  
            */
       259  
           }
           @Parameter(property = "connectionString", defaultValue = "", required = false)
       260  
           /**
           private String connectionString;
       261  
            * The database driver name. An example would be org.h2.Driver.
       
       262  
            */
       263  
           @Parameter(property = "databaseDriverName", defaultValue = "", required = false)
       264  
           private String databaseDriverName;
       265  
           /**
       263  
            * Returns the connection string.
       264  
            *
       265  
            * @return the connection string
       266  
            * The path to the database driver if it is not on the class path.
       267  
            */
       268  
           @Parameter(property = "databaseDriverPath", defaultValue = "", required = false)
       267  
           protected String getConnectionString() {
       268  0
               return connectionString;
       269  
           private String databaseDriverPath;
           }
       270  
           /**
       271  
            * The server id in the settings.xml; used to retrieve encrypted passwords from the settings.xml.
            * The database driver name. An example would be org.h2.Driver.
       272  
            */
       273  
           @Parameter(property = "serverId", defaultValue = "", required = false)
           @Parameter(property = "databaseDriverName", defaultValue = "", required = false)
       274  
           private String serverId;
           private String databaseDriverName;
       275  
           /**
       276  
            * A reference to the settings.xml settings.
            * The path to the database driver if it is not on the class path.
       277  
            */
       278  
           @Parameter(defaultValue = "${settings}", readonly = true, required = true)
           @Parameter(property = "databaseDriverPath", defaultValue = "", required = false)
       279  
           private org.apache.maven.settings.Settings settingsXml;
           private String databaseDriverPath;
       280  
           /**
       281  
            * The security dispatcher that can decrypt passwords in the settings.xml.
            * The server id in the settings.xml; used to retrieve encrypted passwords
       282  
            */
            * from the settings.xml.
       283  
           @Component(role = SecDispatcher.class, hint = "default")
            */
       284  
           private SecDispatcher securityDispatcher;
           @Parameter(property = "serverId", defaultValue = "", required = false)
       285  
           /**
           private String serverId;
       286  
            * The database user name.
           /**
       287  
            */
            * A reference to the settings.xml settings.
       288  
           @Parameter(property = "databaseUser", defaultValue = "", required = false)
            */
       289  
           private String databaseUser;
           @Parameter(defaultValue = "${settings}", readonly = true, required = true)
       290  
           /**
           private org.apache.maven.settings.Settings settingsXml;
       291  
            * The password to use when connecting to the database.
           /**
       292  
            */
            * The security dispatcher that can decrypt passwords in the settings.xml.
       293  
           @Parameter(property = "databasePassword", defaultValue = "", required = false)
            */
       294  
           private String databasePassword;
           @Component(role = SecDispatcher.class, hint = "default")
       295  
           /**
           private SecDispatcher securityDispatcher;
       296  
            * A comma-separated list of file extensions to add to analysis next to jar, zip, ....
       297  
            */
       298  
           @Parameter(property = "zipExtensions", required = false)
       299  
           private String zipExtensions;
       300  
           /**
       301  
            * Skip Dependency Check altogether.
       302  
       297  
            * The database user name.
       298  
            */
       299  
           @Parameter(property = "databaseUser", defaultValue = "", required = false)
       300  
           private String databaseUser;
       301  
           /**
       302  
            * The password to use when connecting to the database.
       303  
            */
       303  0
           @SuppressWarnings("CanBeFinal")
       304  
           @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false)
           @Parameter(property = "databasePassword", defaultValue = "", required = false)
       305  
           private boolean skip = false;
           private String databasePassword;
       306  
           /**
       307  
            * Skip Analysis for Test Scope Dependencies.
            * A comma-separated list of file extensions to add to analysis next to jar,
       308  
            * zip, ....
       309  
            */
       309  0
           @SuppressWarnings("CanBeFinal")
       310  
           @Parameter(property = "skipTestScope", defaultValue = "true", required = false)
           @Parameter(property = "zipExtensions", required = false)
       311  
           private boolean skipTestScope = true;
           private String zipExtensions;
       312  
           /**
       313  
            * Skip Analysis for Runtime Scope Dependencies.
            * Skip Dependency Check altogether.
       314  
            */
       315  0
           @SuppressWarnings("CanBeFinal")
       316  
           @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false)
           @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false)
       317  
           private boolean skipRuntimeScope = false;
           private boolean skip = false;
       318  
           /**
       319  
            * Skip Analysis for Provided Scope Dependencies.
            * Skip Analysis for Test Scope Dependencies.
       320  
            */
       321  0
           @SuppressWarnings("CanBeFinal")
       322  
           @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false)
           @Parameter(property = "skipTestScope", defaultValue = "true", required = false)
       323  
           private boolean skipProvidedScope = false;
           private boolean skipTestScope = true;
       324  
           /**
       325  
            * The data directory, hold DC SQL DB.
            * Skip Analysis for Runtime Scope Dependencies.
       326  
            */
       327  
           @Parameter(property = "dataDirectory", defaultValue = "", required = false)
       327  0
           @SuppressWarnings("CanBeFinal")
       328  
           private String dataDirectory;
           @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false)
       329  
           /**
           private boolean skipRuntimeScope = false;
       330  
            * Data Mirror URL for CVE 1.2.
           /**
       331  
            */
            * Skip Analysis for Provided Scope Dependencies.
       332  
           @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false)
       333  
           private String cveUrl12Modified;
            */
       333  0
           @SuppressWarnings("CanBeFinal")
       334  
           /**
           @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false)
       335  
            * Data Mirror URL for CVE 2.0.
           private boolean skipProvidedScope = false;
       336  
            */
           /**
       337  
           @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false)
            * The data directory, hold DC SQL DB.
       338  
           private String cveUrl20Modified;
            */
       339  
           /**
           @Parameter(property = "dataDirectory", defaultValue = "", required = false)
       340  
            * Base Data Mirror URL for CVE 1.2.
           private String dataDirectory;
       341  
            */
           /**
       342  
           @Parameter(property = "cveUrl12Base", defaultValue = "", required = false)
            * Data Mirror URL for CVE 1.2.
       343  
           private String cveUrl12Base;
            */
       344  
           /**
           @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false)
       345  
            * Data Mirror URL for CVE 2.0.
           private String cveUrl12Modified;
       346  
            */
           /**
       347  
           @Parameter(property = "cveUrl20Base", defaultValue = "", required = false)
            * Data Mirror URL for CVE 2.0.
       348  
           private String cveUrl20Base;
            */
       349  
           /**
           @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false)
       350  
            * Optionally skip excessive CVE update checks for a designated duration in hours.
           private String cveUrl20Modified;
       351  
            */
       352  
           @Parameter(property = "cveValidForHours", defaultValue = "", required = false)
       353  
           private Integer cveValidForHours;
       354  
       
       355  
           /**
       356  
            * The path to mono for .NET Assembly analysis on non-windows systems.
       357  
       352  
            * Base Data Mirror URL for CVE 1.2.
       353  
            */
       354  
           @Parameter(property = "cveUrl12Base", defaultValue = "", required = false)
       355  
           private String cveUrl12Base;
       356  
           /**
       357  
            * Data Mirror URL for CVE 2.0.
       358  
           @Parameter(property = "pathToMono", defaultValue = "", required = false)
            */
       359  
           private String pathToMono;
           @Parameter(property = "cveUrl20Base", defaultValue = "", required = false)
       360  
       
           private String cveUrl20Base;
       361  
           /**
       362  
            * The Proxy URL.
            * Optionally skip excessive CVE update checks for a designated duration in
       363  
            *
            * hours.
       364  
            * @deprecated Please use mavenSettings instead
            */
       365  
            */
       366  0
           @SuppressWarnings("CanBeFinal")
           @Parameter(property = "cveValidForHours", defaultValue = "", required = false)
       366  
           private Integer cveValidForHours;
       367  
           @Parameter(property = "proxyUrl", defaultValue = "", required = false)
       368  
           @Deprecated
       369  
           private String proxyUrl = null;
       370  
           /**
       371  
            * Sets whether or not the external report format should be used.
       372  
            *
       373  
            * @deprecated the internal report is no longer supported
       374  
            */
       375  0
           @SuppressWarnings("CanBeFinal")
       376  
           @Parameter(property = "externalReport")
       377  
           @Deprecated
       378  
           private String externalReport = null;
       379  
           // </editor-fold>
       380  
           //<editor-fold defaultstate="collapsed" desc="Base Maven implementation">
       381  
       
       382  
       368  
           /**
       383  
            * Executes dependency-check.
       384  
       369  
            * The path to mono for .NET Assembly analysis on non-windows systems.
       370  
            */
       371  
           @Parameter(property = "pathToMono", defaultValue = "", required = false)
       372  
           private String pathToMono;
       373  
       
       374  
           /**
       375  
            * The Proxy URL.
       376  
            *
       377  
            * @deprecated Please use mavenSettings instead
       378  
            */
       379  0
           @SuppressWarnings("CanBeFinal")
       380  
           @Parameter(property = "proxyUrl", defaultValue = "", required = false)
       381  
           @Deprecated
       382  
           private String proxyUrl = null;
       383  
           /**
       384  
            * Sets whether or not the external report format should be used.
       385  
            * @throws MojoExecutionException thrown if there is an exception executing the mojo
            *
       386  
            * @throws MojoFailureException thrown if dependency-check failed the build
            * @deprecated the internal report is no longer supported
       387  
            */
       388  
           @Override
       388  0
           @SuppressWarnings("CanBeFinal")
       389  
           public void execute() throws MojoExecutionException, MojoFailureException {
       390  0
               generatingSite = false;
       391  0
               if (skip) {
       392  0
                   getLog().info("Skipping " + getName(Locale.US));
           @Parameter(property = "externalReport")
       390  
           @Deprecated
       391  
           private String externalReport = null;
       392  
           // </editor-fold>
       393  
               } else {
       394  0
                   validateAggregate();
       395  0
                   project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory);
       396  0
                   runCheck();
       397  
               }
       398  0
           }
       399  
           //<editor-fold defaultstate="collapsed" desc="Base Maven implementation">
       394  
       
       400  
       395  
           /**
       401  
            * Checks if the aggregate configuration parameter has been set to true. If it has a MojoExecutionException is thrown because
       402  
            * the aggregate configuration parameter is no longer supported.
       403  
       396  
            * Executes dependency-check.
       397  
            *
       404  
            * @throws MojoExecutionException thrown if aggregate is set to true
       405  
       398  
            * @throws MojoExecutionException thrown if there is an exception executing
       399  
            * the mojo
       400  
            * @throws MojoFailureException thrown if dependency-check failed the build
       401  
            */
       406  
           private void validateAggregate() throws MojoExecutionException {
       407  0
               if (aggregate != null && aggregate) {
       408  0
                   final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. "
       409  
                           + "Please use the aggregate goal instead.";
       410  0
                   throw new MojoExecutionException(msg);
       402  
           @Override
       403  
           public void execute() throws MojoExecutionException, MojoFailureException {
       404  0
               generatingSite = false;
       405  0
               if (skip) {
       406  0
                   getLog().info("Skipping " + getName(Locale.US));
       407  
               } else {
       408  0
                   validateAggregate();
       409  0
                   project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory);
       410  0
                   runCheck();
       411  
               }
       412  0
           }
       414  
           /**
       415  
            * Generates the Dependency-Check Site Report.
            * Checks if the aggregate configuration parameter has been set to true. If
       416  
            *
            * it has a MojoExecutionException is thrown because the aggregate
       417  
            * @param sink the sink to write the report to
            * configuration parameter is no longer supported.
       418  
            * @param locale the locale to use when generating the report
            *
       419  
            * @throws MavenReportException if a maven report exception occurs
            * @throws MojoExecutionException thrown if aggregate is set to true
       420  
            * @deprecated use {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} instead.
            */
       421  
            */
       422  
           @Override
       423  
           @Deprecated
           private void validateAggregate() throws MojoExecutionException {
       422  0
               if (aggregate != null && aggregate) {
       423  0
                   final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. "
       424  
           public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException {
       425  0
               generate((Sink) sink, locale);
       426  0
           }
       427  
       
                           + "Please use the aggregate goal instead.";
       425  0
                   throw new MojoExecutionException(msg);
       426  
               }
       427  0
           }
       428  
           /**
       
       429  
            * A flag indicating whether or not the maven site is being generated.
           /**
       430  
            */
       431  0
           private boolean generatingSite = false;
       432  
       
       433  
           /**
       434  
            * Returns true if the Maven site is being generated.
       435  
            *
       436  
            * @return true if the Maven site is being generated
       437  
            */
       438  
           protected boolean isGeneratingSite() {
       439  0
               return generatingSite;
       440  
           }
       441  
       
       442  
           /**
       443  
            * Generates the Dependency-Check Site Report.
       444  
       431  
            *
       445  
       432  
            * @param sink the sink to write the report to
       446  
       433  
            * @param locale the locale to use when generating the report
       447  
       434  
            * @throws MavenReportException if a maven report exception occurs
       448  
       435  
            * @deprecated use
       436  
            * {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)}
       437  
            * instead.
       438  
            */
       449  
           public void generate(Sink sink, Locale locale) throws MavenReportException {
       450  0
               generatingSite = true;
       451  
               try {
       452  0
                   validateAggregate();
       453  0
               } catch (MojoExecutionException ex) {
       454  0
                   throw new MavenReportException(ex.getMessage());
       455  0
               }
       456  0
               project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory());
       457  
               try {
       458  0
                   runCheck();
       459  0
               } catch (MojoExecutionException ex) {
       460  0
                   throw new MavenReportException(ex.getMessage(), ex);
       461  0
               } catch (MojoFailureException ex) {
       462  0
                   getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build");
       463  0
               }
       464  0
           }
       465  
       
       466  
           /**
       467  
            * Returns the correct output directory depending on if a site is being executed or not.
       468  
            *
       469  
            * @return the directory to write the report(s)
       470  
            * @throws MojoExecutionException thrown if there is an error loading the file path
       471  
            */
       472  
           protected File getCorrectOutputDirectory() throws MojoExecutionException {
       473  0
               return getCorrectOutputDirectory(this.project);
       474  
           }
       475  
       
       476  
           /**
       477  
            * Returns the correct output directory depending on if a site is being executed or not.
       478  
            *
       479  
            * @param current the Maven project to get the output directory from
       480  
            * @return the directory to write the report(s)
       481  
            */
       482  
           protected File getCorrectOutputDirectory(MavenProject current) {
       483  0
               final Object obj = current.getContextValue(getOutputDirectoryContextKey());
       484  0
               if (obj != null && obj instanceof File) {
       485  0
                   return (File) obj;
       486  
               }
       487  0
               File target = new File(current.getBuild().getDirectory());
       488  0
               if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) {
       489  0
                   target = target.getParentFile();
       490  
               }
       491  0
               return target;
       492  
           }
       493  
       
       494  
           /**
       495  
            * Returns the correct output directory depending on if a site is being executed or not.
       496  
            *
       497  
            * @param current the Maven project to get the output directory from
       498  
            * @return the directory to write the report(s)
       499  
            */
       500  
           protected File getDataFile(MavenProject current) {
       501  0
               if (getLog().isDebugEnabled()) {
       502  0
                   getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey()));
       503  
               }
       504  0
               final Object obj = current.getContextValue(getDataFileContextKey());
       505  0
               if (obj != null) {
       506  0
                   if (obj instanceof String) {
       507  0
                       final File f = new File((String) obj);
       508  0
                       return f;
       509  
                   }
       510  
               } else {
       511  0
                   if (getLog().isDebugEnabled()) {
       512  0
                       getLog().debug("Context value not found");
       513  
                   }
       514  
               }
       515  0
               return null;
       516  
           }
       517  
       
       518  
           /**
       519  
            * Scans the project's artifacts and adds them to the engine's dependency list.
       520  
            *
       521  
            * @param project the project to scan the dependencies of
       522  
            * @param engine the engine to use to scan the dependencies
       523  
            */
       524  
           protected void scanArtifacts(MavenProject project, Engine engine) {
       525  0
               for (Artifact a : project.getArtifacts()) {
       526  0
                   if (excludeFromScan(a)) {
       527  0
                       continue;
       528  
                   }
       529  0
                   final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile());
       530  0
                   if (deps != null) {
       531  0
                       if (deps.size() == 1) {
       532  0
                           final Dependency d = deps.get(0);
       533  0
                           if (d != null) {
       534  0
                               final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion());
       535  0
                               d.addAsEvidence("pom", ma, Confidence.HIGHEST);
       536  0
                               d.addProjectReference(project.getName());
       537  0
                               if (getLog().isDebugEnabled()) {
       538  0
                                   getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(),
       539  0
                                           d.getDisplayFileName()));
       540  
                               }
       541  
                           }
       542  0
                       } else {
       543  0
                           if (getLog().isDebugEnabled()) {
       544  0
                               final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'",
       545  0
                                       a.getGroupId(), a.getArtifactId(), a.getVersion());
       546  0
                               getLog().debug(msg);
       547  
                           }
       548  
                       }
       549  
                   }
       550  0
               }
       551  0
           }
       552  
       
       553  
           /**
       554  
            * Executes the dependency-check scan and generates the necassary report.
       555  
            *
       556  
            * @throws MojoExecutionException thrown if there is an exception running the scan
       557  
            * @throws MojoFailureException thrown if dependency-check is configured to fail the build
       558  
            */
       559  
           public abstract void runCheck() throws MojoExecutionException, MojoFailureException;
       560  
       
       561  
           /**
       562  
            * Sets the Reporting output directory.
       563  
            *
       564  
            * @param directory the output directory
       565  
            */
       566  
       439  
           @Override
       440  
           @Deprecated
       441  
           public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException {
       442  0
               generate((Sink) sink, locale);
       443  0
           }
       444  
       
       445  
           /**
       446  
            * A flag indicating whether or not the maven site is being generated.
       447  
            */
       448  0
           private boolean generatingSite = false;
       449  
       
       450  
           /**
       451  
            * Returns true if the Maven site is being generated.
       452  
            *
       453  
            * @return true if the Maven site is being generated
       454  
            */
       455  
           protected boolean isGeneratingSite() {
       456  0
               return generatingSite;
       457  
           }
       458  
       
       459  
           /**
       460  
            * Generates the Dependency-Check Site Report.
       461  
            *
       462  
            * @param sink the sink to write the report to
       463  
            * @param locale the locale to use when generating the report
       464  
            * @throws MavenReportException if a maven report exception occurs
       465  
            */
       466  
           public void generate(Sink sink, Locale locale) throws MavenReportException {
       467  0
               generatingSite = true;
       468  
               try {
       469  0
                   validateAggregate();
       470  0
               } catch (MojoExecutionException ex) {
       471  0
                   throw new MavenReportException(ex.getMessage());
       472  0
               }
       473  0
               project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory());
       474  
               try {
       475  0
                   runCheck();
       476  0
               } catch (MojoExecutionException ex) {
       477  0
                   throw new MavenReportException(ex.getMessage(), ex);
       478  0
               } catch (MojoFailureException ex) {
       479  0
                   getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build");
       480  0
               }
       481  0
           }
       482  
       
       483  
           /**
       484  
            * Returns the correct output directory depending on if a site is being
       485  
            * executed or not.
       486  
            *
       487  
            * @return the directory to write the report(s)
       488  
            * @throws MojoExecutionException thrown if there is an error loading the
       489  
            * file path
       490  
            */
       491  
           protected File getCorrectOutputDirectory() throws MojoExecutionException {
       492  0
               return getCorrectOutputDirectory(this.project);
       493  
           }
       494  
       
       495  
           /**
       496  
            * Returns the correct output directory depending on if a site is being
       497  
            * executed or not.
       498  
            *
       499  
            * @param current the Maven project to get the output directory from
       500  
            * @return the directory to write the report(s)
       501  
            */
       502  
           protected File getCorrectOutputDirectory(MavenProject current) {
       503  0
               final Object obj = current.getContextValue(getOutputDirectoryContextKey());
       504  0
               if (obj != null && obj instanceof File) {
       505  0
                   return (File) obj;
       506  
               }
       507  0
               File target = new File(current.getBuild().getDirectory());
       508  0
               if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) {
       509  0
                   target = target.getParentFile();
       510  
               }
       511  0
               return target;
       512  
           }
       513  
       
       514  
           /**
       515  
            * Returns the correct output directory depending on if a site is being
       516  
            * executed or not.
       517  
            *
       518  
            * @param current the Maven project to get the output directory from
       519  
            * @return the directory to write the report(s)
       520  
            */
       521  
           protected File getDataFile(MavenProject current) {
       522  0
               if (getLog().isDebugEnabled()) {
       523  0
                   getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey()));
       524  
               }
       525  0
               final Object obj = current.getContextValue(getDataFileContextKey());
       526  0
               if (obj != null) {
       527  0
                   if (obj instanceof String) {
       528  0
                       final File f = new File((String) obj);
       529  0
                       return f;
       530  
                   }
       531  0
               } else if (getLog().isDebugEnabled()) {
       532  0
                   getLog().debug("Context value not found");
       533  
               }
       534  0
               return null;
       535  
           }
       536  
       
       537  
           /**
       538  
            * Scans the project's artifacts and adds them to the engine's dependency
       539  
            * list.
       540  
            *
       541  
            * @param project the project to scan the dependencies of
       542  
            * @param engine the engine to use to scan the dependencies
       543  
            */
       544  
           protected void scanArtifacts(MavenProject project, Engine engine) {
       545  0
               for (Artifact a : project.getArtifacts()) {
       546  0
                   if (excludeFromScan(a)) {
       547  0
                       continue;
       548  
                   }
       549  0
                   final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile());
       550  0
                   if (deps != null) {
       551  0
                       if (deps.size() == 1) {
       552  0
                           final Dependency d = deps.get(0);
       553  0
                           if (d != null) {
       554  0
                               final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion());
       555  0
                               d.addAsEvidence("pom", ma, Confidence.HIGHEST);
       556  0
                               d.addProjectReference(project.getName());
       557  0
                               if (getLog().isDebugEnabled()) {
       558  0
                                   getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(),
       559  0
                                           d.getDisplayFileName()));
       560  
                               }
       561  
                           }
       562  0
                       } else if (getLog().isDebugEnabled()) {
       563  0
                           final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'",
       564  0
                                   a.getGroupId(), a.getArtifactId(), a.getVersion());
       565  0
                           getLog().debug(msg);
       566  
                       }
       567  
           public void setReportOutputDirectory(File directory) {
       568  0
               reportOutputDirectory = directory;
                   }
       568  0
               }
       569  0
           }
       570  
       
       571  
           /**
       572  
            * Returns the report output directory.
            * Executes the dependency-check scan and generates the necassary report.
       573  
            *
       574  
            * @return the report output directory
            * @throws MojoExecutionException thrown if there is an exception running
       575  
            */
            * the scan
       576  
           @Override
            * @throws MojoFailureException thrown if dependency-check is configured to
       577  
           public File getReportOutputDirectory() {
       578  0
               return reportOutputDirectory;
            * fail the build
       578  
            */
       579  
           }
           public abstract void runCheck() throws MojoExecutionException, MojoFailureException;
       580  
       
       581  
           /**
       582  
            * Returns the output directory.
            * Sets the Reporting output directory.
       583  
            *
       584  
            * @return the output directory
            * @param directory the output directory
       585  
            */
       586  
           public File getOutputDirectory() {
       587  0
               return outputDirectory;
       588  
           }
       589  
       
           @Override
       587  
           public void setReportOutputDirectory(File directory) {
       588  0
               reportOutputDirectory = directory;
       589  0
           }
       590  
           /**
       
       591  
            * Returns whether this is an external report. This method always returns true.
           /**
       592  
            *
            * Returns the report output directory.
       593  
            * @return <code>true</code>
            *
       594  
            */
            * @return the report output directory
       595  
           @Override
            */
       596  
           public final boolean isExternalReport() {
       597  0
               return true;
       598  
           }
           @Override
       597  
           public File getReportOutputDirectory() {
       598  0
               return reportOutputDirectory;
       599  
       
           }
       600  
           /**
       
       601  
            * Returns the output name.
           /**
       602  
            *
            * Returns the output directory.
       603  
            * @return the output name
            *
       604  
            */
            * @return the output directory
       605  
           @Override
            */
       606  
           public String getOutputName() {
       607  0
               if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) {
       608  0
                   return "dependency-check-report";
       609  0
               } else if ("XML".equalsIgnoreCase(this.format)) {
       610  0
                   return "dependency-check-report.xml#";
       611  0
               } else if ("VULN".equalsIgnoreCase(this.format)) {
       612  0
                   return "dependency-check-vulnerability";
           public File getOutputDirectory() {
       607  0
               return outputDirectory;
       608  
           }
       609  
       
       610  
           /**
       611  
            * Returns whether this is an external report. This method always returns
       612  
            * true.
       613  
               } else {
       614  0
                   getLog().warn("Unknown report format used during site generation.");
       615  0
                   return "dependency-check-report";
            *
       614  
            * @return <code>true</code>
       615  
            */
       616  
               }
       617  
           }
       618  
       
       619  
           /**
       620  
            * Returns the category name.
       621  
            *
       622  
            * @return the category name
       623  
            */
       624  
           @Override
       625  
           public String getCategoryName() {
       626  0
               return MavenReport.CATEGORY_PROJECT_REPORTS;
       627  
       617  
           public final boolean isExternalReport() {
       618  0
               return true;
       619  
           }
       628  
           //</editor-fold>
       629  
       620  
       
       630  
       621  
           /**
       631  
            * Initializes a new <code>Engine</code> that can be used for scanning.
       632  
       622  
            * Returns the output name.
       623  
            *
       633  
            * @return a newly instantiated <code>Engine</code>
       624  
            * @return the output name
       625  
            */
       626  
           @Override
       627  
           public String getOutputName() {
       628  0
               if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) {
       629  0
                   return "dependency-check-report";
       630  0
               } else if ("XML".equalsIgnoreCase(this.format)) {
       631  0
                   return "dependency-check-report.xml#";
       632  0
               } else if ("VULN".equalsIgnoreCase(this.format)) {
       633  0
                   return "dependency-check-vulnerability";
       634  
            * @throws DatabaseException thrown if there is a database exception
       635  
            */
       636  
           protected Engine initializeEngine() throws DatabaseException {
       637  0
               populateSettings();
       638  0
               return new Engine(this.project,
       639  
                       this.reactorProjects);
       640  
               } else {
       635  0
                   getLog().warn("Unknown report format used during site generation.");
       636  0
                   return "dependency-check-report";
       637  
               }
       638  
           }
       641  
       639  
       
       642  
       640  
           /**
       641  
            * Returns the category name.
       642  
            *
       643  
            * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
            * @return the category name
       644  
            * required to change the proxy url, port, and connection timeout.
       645  
            */
       645  
           @Override
       646  
           protected void populateSettings() {
       647  0
               Settings.initialize();
       648  0
               InputStream mojoProperties = null;
           public String getCategoryName() {
       647  0
               return MavenReport.CATEGORY_PROJECT_REPORTS;
       648  
           }
       649  
               try {
       650  0
                   mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
       651  0
                   Settings.mergeProperties(mojoProperties);
       652  0
               } catch (IOException ex) {
       653  0
                   getLog().warn("Unable to load the dependency-check ant task.properties file.");
       654  0
                   if (getLog().isDebugEnabled()) {
       655  0
                       getLog().debug("", ex);
           //</editor-fold>
       650  
       
       651  
           /**
       652  
            * Initializes a new <code>Engine</code> that can be used for scanning.
       653  
            *
       654  
            * @return a newly instantiated <code>Engine</code>
       655  
            * @throws DatabaseException thrown if there is a database exception
       656  
                   }
            */
       657  
               } finally {
       658  0
                   if (mojoProperties != null) {
       659  
                       try {
       660  0
                           mojoProperties.close();
       661  0
                       } catch (IOException ex) {
       662  0
                           if (getLog().isDebugEnabled()) {
       663  0
                               getLog().debug("", ex);
           protected Engine initializeEngine() throws DatabaseException {
       658  0
               populateSettings();
       659  0
               return new Engine(this.project,
       660  
                       this.reactorProjects);
       661  
           }
       662  
       
       663  
           /**
       664  
                           }
       665  0
                       }
            * Takes the properties supplied and updates the dependency-check settings.
       665  
            * Additionally, this sets the system properties required to change the
       666  
                   }
            * proxy url, port, and connection timeout.
       667  
               }
       668  0
               Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
       669  
       
       670  0
               if (externalReport != null) {
       671  0
                   getLog().warn("The 'externalReport' option was set; this configuration option has been removed. "
       672  
                           + "Please update the dependency-check-maven plugin's configuration");
       673  
               }
       674  
       
       675  0
               if (proxyUrl != null && !proxyUrl.isEmpty()) {
       676  0
                   getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead");
       677  
               }
       678  0
               final Proxy proxy = getMavenProxy();
       679  0
               if (proxy != null) {
       680  0
                   Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost());
       681  0
                   Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort()));
       682  0
                   final String userName = proxy.getUsername();
       683  0
                   final String password = proxy.getPassword();
       684  0
                   Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName);
       685  0
                   Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password);
       686  0
                   Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts());
       687  
               }
            */
       668  
           protected void populateSettings() {
       669  0
               Settings.initialize();
       670  0
               InputStream mojoProperties = null;
       671  
               try {
       672  0
                   mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
       673  0
                   Settings.mergeProperties(mojoProperties);
       674  0
               } catch (IOException ex) {
       675  0
                   getLog().warn("Unable to load the dependency-check ant task.properties file.");
       676  0
                   if (getLog().isDebugEnabled()) {
       677  0
                       getLog().debug("", ex);
       678  
                   }
       679  
               } finally {
       680  0
                   if (mojoProperties != null) {
       681  
                       try {
       682  0
                           mojoProperties.close();
       683  0
                       } catch (IOException ex) {
       684  0
                           if (getLog().isDebugEnabled()) {
       685  0
                               getLog().debug("", ex);
       686  
                           }
       687  0
                       }
       688  
       
       689  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
       690  0
               Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
                   }
       689  
               }
       690  0
               Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
       691  
       
       692  
               //File Type Analyzer Settings
       693  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
       694  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
       695  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
       696  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
       697  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
       698  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
       699  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
       700  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
       701  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
       702  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
       703  
       692  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental);
       693  
       
       704  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled);
       705  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled);
       706  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled);
       707  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled);
       708  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled);
       709  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled);
       710  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled);
       711  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled);
       694  0
               if (externalReport != null) {
       695  0
                   getLog().warn("The 'externalReport' option was set; this configuration option has been removed. "
       696  
                           + "Please update the dependency-check-maven plugin's configuration");
       697  
               }
       698  
       
       699  0
               if (proxyUrl != null && !proxyUrl.isEmpty()) {
       700  0
                   getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead");
       701  
               }
       702  0
               final Proxy proxy = getMavenProxy();
       703  0
               if (proxy != null) {
       704  0
                   Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost());
       705  0
                   Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort()));
       706  0
                   final String userName = proxy.getUsername();
       707  0
                   final String password = proxy.getPassword();
       708  0
                   Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName);
       709  0
                   Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password);
       710  0
                   Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts());
       711  
               }
       712  
       
       713  
               //Database configuration
       714  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
       715  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
       716  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
       717  
       713  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
       714  0
               Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
       715  
       
       718  0
               if (databaseUser == null && databasePassword == null && serverId != null) {
       719  0
                   final Server server = settingsXml.getServer(serverId);
       720  0
                   if (server != null) {
       721  0
                       databaseUser = server.getUsername();
       722  
                       try {
       723  
                           //The following fix was copied from:
       724  
                           //   https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java
       725  
                           //
       726  
                           // FIX to resolve
       716  
               //File Type Analyzer Settings
       717  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
       718  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
       719  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
       720  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
       721  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
       722  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
       723  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
       724  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
       725  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
       726  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
       727  
                           // org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException:
       728  
                           // java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory)
       729  
                           //
       730  0
                           if (securityDispatcher instanceof DefaultSecDispatcher) {
       731  0
                               ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml");
       732  
                           }
       733  
       
       734  0
                           databasePassword = securityDispatcher.decrypt(server.getPassword());
       735  0
                       } catch (SecDispatcherException ex) {
       736  0
                           if (ex.getCause() instanceof FileNotFoundException
       737  0
                                   || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) {
       738  
                               //maybe its not encrypted?
       739  0
                               final String tmp = server.getPassword();
       740  0
                               if (tmp.startsWith("{") && tmp.endsWith("}")) {
       741  0
                                   getLog().error(String.format(
       742  
                                           "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s",
       743  0
                                           serverId, ex.getMessage()));
       744  
                               } else {
       745  0
                                   databasePassword = tmp;
       728  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled);
       729  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled);
       730  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled);
       731  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled);
       732  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled);
       733  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled);
       734  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled);
       735  0
               Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled);
       736  
       
       737  
               //Database configuration
       738  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
       739  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
       740  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
       741  
       
       742  0
               if (databaseUser == null && databasePassword == null && serverId != null) {
       743  0
                   final Server server = settingsXml.getServer(serverId);
       744  0
                   if (server != null) {
       745  0
                       databaseUser = server.getUsername();
       746  
                               }
       747  0
                           } else {
       748  0
                               getLog().error(String.format(
                       try {
       747  
                           //The following fix was copied from:
       748  
                           //   https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java
       749  
                                       "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s",
       750  0
                                       serverId, ex.getMessage()));
                           //
       750  
                           // FIX to resolve
       751  
                           }
       752  0
                       }
                           // org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException:
       752  
                           // java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory)
       753  
                   } else {
       754  0
                       getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId));
       755  
                   }
                           //
       754  0
                           if (securityDispatcher instanceof DefaultSecDispatcher) {
       755  0
                               ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml");
       756  
               }
                           }
       757  
       
       758  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
       759  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
       760  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
       761  
       
       762  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
       763  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
       764  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
       765  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
       766  0
               Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
       767  
       
       768  0
           }
       769  
       
       770  
           /**
       771  
            * Returns the maven proxy.
       772  
            *
       773  
            * @return the maven proxy
       774  
            */
       775  
           private Proxy getMavenProxy() {
       776  0
               if (mavenSettings != null) {
       777  0
                   final List<Proxy> proxies = mavenSettings.getProxies();
       778  0
                   if (proxies != null && !proxies.isEmpty()) {
       779  0
                       if (mavenSettingsProxyId != null) {
       780  0
                           for (Proxy proxy : proxies) {
       781  0
                               if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) {
       782  0
                                   return proxy;
       783  
                               }
       784  0
                           }
       785  0
                       } else if (proxies.size() == 1) {
       786  0
                           return proxies.get(0);
       787  
                       } else {
       788  0
                           getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check "
       789  
                                   + "configuration set the mavenSettingsProxyId so that the correct proxy will be used.");
       790  0
                           throw new IllegalStateException("Ambiguous proxy definition");
       791  
                       }
       792  
                   }
       793  
               }
       794  0
               return null;
       795  
           }
       796  
       
       797  
           /**
       798  
            * Tests is the artifact should be included in the scan (i.e. is the dependency in a scope that is being scanned).
       799  
            *
       800  
            * @param a the Artifact to test
       801  
            * @return <code>true</code> if the artifact is in an excluded scope; otherwise <code>false</code>
       802  
            */
       803  
           protected boolean excludeFromScan(Artifact a) {
       804  0
               if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) {
       805  0
                   return true;
       806  
               }
       807  0
               if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) {
       808  0
                   return true;
       809  
               }
       810  0
               if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) {
       811  0
                   return true;
       812  
               }
       813  0
               return false;
       814  
           }
       815  
       
       816  
           /**
       817  
            * Returns a reference to the current project. This method is used instead of auto-binding the project via component
       818  
            * annotation in concrete implementations of this. If the child has a <code>@Component MavenProject project;</code> defined
       819  
            * then the abstract class (i.e. this class) will not have access to the current project (just the way Maven works with the
       820  
            * binding).
       821  
            *
       822  
            * @return returns a reference to the current project
       823  
            */
       824  
           protected MavenProject getProject() {
       825  0
               return project;
       826  
           }
       827  
       
       828  
           /**
       829  
            * Returns the list of Maven Projects in this build.
       830  
            *
       831  
            * @return the list of Maven Projects in this build
       832  
            */
       833  
           protected List<MavenProject> getReactorProjects() {
       834  0
               return reactorProjects;
       835  
           }
       836  
       
       837  
           /**
       838  
            * Returns the report format.
       839  
            *
       840  
            * @return the report format
       841  
            */
       842  
           protected String getFormat() {
       843  0
               return format;
       844  
           }
       845  
       
       846  
           /**
       847  
            * Generates the reports for a given dependency-check engine.
       848  
            *
       849  
            * @param engine a dependency-check engine
       850  
            * @param p the maven project
       851  
            * @param outputDir the directory path to write the report(s).
       852  
            */
       853  
           protected void writeReports(Engine engine, MavenProject p, File outputDir) {
       854  0
               DatabaseProperties prop = null;
       855  0
               CveDB cve = null;
       856  
               try {
       857  0
                   cve = new CveDB();
       858  0
                   cve.open();
       859  0
                   prop = cve.getDatabaseProperties();
       860  0
               } catch (DatabaseException ex) {
       861  0
                   if (getLog().isDebugEnabled()) {
       862  0
                       getLog().debug("Unable to retrieve DB Properties", ex);
       863  
                   }
       864  
               } finally {
       865  0
                   if (cve != null) {
       866  0
                       cve.close();
       867  
                   }
       868  
               }
       869  0
               final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop);
       870  
               try {
       871  0
                   r.generateReports(outputDir.getAbsolutePath(), format);
       872  0
               } catch (IOException ex) {
       873  0
                   getLog().error(
       874  
                           "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
       875  0
                   if (getLog().isDebugEnabled()) {
       876  0
                       getLog().debug("", ex);
       877  
                   }
       878  0
               } catch (Throwable ex) {
       879  0
                   getLog().error(
       880  
                           "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
       881  0
                   if (getLog().isDebugEnabled()) {
       882  0
                       getLog().debug("", ex);
       883  
                   }
       884  0
               }
       885  0
           }
       886  
       
       887  
           //<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary">
       888  
           /**
       889  
            * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the
       890  
            * configuration.
       891  
            *
       892  
            * @param dependencies the list of dependency objects
       893  
            * @throws MojoFailureException thrown if a CVSS score is found that is higher then the threshold set
       894  
            */
       895  
           protected void checkForFailure(List<Dependency> dependencies) throws MojoFailureException {
       896  0
               if (failBuildOnCVSS <= 10) {
       897  0
                   final StringBuilder ids = new StringBuilder();
       898  0
                   for (Dependency d : dependencies) {
       899  0
                       boolean addName = true;
       900  0
                       for (Vulnerability v : d.getVulnerabilities()) {
       901  0
                           if (v.getCvssScore() >= failBuildOnCVSS) {
       902  0
                               if (addName) {
       903  0
                                   addName = false;
       904  0
                                   ids.append(NEW_LINE).append(d.getFileName()).append(": ");
       905  0
                                   ids.append(v.getName());
       906  
       758  0
                           databasePassword = securityDispatcher.decrypt(server.getPassword());
       759  0
                       } catch (SecDispatcherException ex) {
       760  0
                           if (ex.getCause() instanceof FileNotFoundException
       761  0
                                   || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) {
       762  
                               //maybe its not encrypted?
       763  0
                               final String tmp = server.getPassword();
       764  0
                               if (tmp.startsWith("{") && tmp.endsWith("}")) {
       765  0
                                   getLog().error(String.format(
       766  
                                           "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s",
       767  0
                                           serverId, ex.getMessage()));
       768  
                               } else {
       907  0
                                   ids.append(", ").append(v.getName());
       908  
       769  0
                                   databasePassword = tmp;
       770  
                               }
       909  
       771  0
                           } else {
       772  0
                               getLog().error(String.format(
       773  
                                       "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s",
       774  0
                                       serverId, ex.getMessage()));
       775  
                           }
       910  0
                       }
       911  0
                   }
       912  0
                   if (ids.length() > 0) {
       913  0
                       final String msg = String.format("%n%nDependency-Check Failure:%n"
       914  
                               + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
       915  0
                               + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
       916  0
                       throw new MojoFailureException(msg);
       917  
       776  0
                       }
       777  
                   } else {
       778  0
                       getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId));
       779  
                   }
       918  
       780  
               }
       919  0
           }
       920  
       781  
       
       921  
       782  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
       783  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
       784  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
       785  
       
       786  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
       787  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
       788  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
       789  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
       790  0
               Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
       791  
       
       792  0
           }
       793  
       
       794  
           /**
       922  
            * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries.
       923  
       795  
            * Returns the maven proxy.
       796  
            *
       924  
            * @param mp the Maven project for which the summary is shown
       925  
            * @param dependencies a list of dependency objects
       926  
       797  
            * @return the maven proxy
       798  
            */
       927  
           protected void showSummary(MavenProject mp, List<Dependency> dependencies) {
       928  0
               if (showSummary) {
       929  0
                   final StringBuilder summary = new StringBuilder();
       930  0
                   for (Dependency d : dependencies) {
       931  0
                       boolean firstEntry = true;
       932  0
                       final StringBuilder ids = new StringBuilder();
       933  0
                       for (Vulnerability v : d.getVulnerabilities()) {
       934  0
                           if (firstEntry) {
       935  0
                               firstEntry = false;
       936  
                           } else {
       937  0
                               ids.append(", ");
       799  
           private Proxy getMavenProxy() {
       800  0
               if (mavenSettings != null) {
       801  0
                   final List<Proxy> proxies = mavenSettings.getProxies();
       802  0
                   if (proxies != null && !proxies.isEmpty()) {
       803  0
                       if (mavenSettingsProxyId != null) {
       804  0
                           for (Proxy proxy : proxies) {
       805  0
                               if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) {
       806  0
                                   return proxy;
       807  
                               }
       808  0
                           }
       809  0
                       } else if (proxies.size() == 1) {
       810  0
                           return proxies.get(0);
       811  
                       } else {
       812  0
                           getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check "
       813  
                                   + "configuration set the mavenSettingsProxyId so that the correct proxy will be used.");
       814  0
                           throw new IllegalStateException("Ambiguous proxy definition");
       815  
                       }
       816  
                   }
       817  
               }
       818  0
               return null;
       819  
           }
       820  
       
       821  
           /**
       822  
            * Tests is the artifact should be included in the scan (i.e. is the
       823  
            * dependency in a scope that is being scanned).
       824  
            *
       825  
            * @param a the Artifact to test
       826  
            * @return <code>true</code> if the artifact is in an excluded scope;
       827  
            * otherwise <code>false</code>
       828  
            */
       829  
           protected boolean excludeFromScan(Artifact a) {
       830  0
               if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) {
       831  0
                   return true;
       832  
               }
       833  0
               if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) {
       834  0
                   return true;
       835  
               }
       836  0
               if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) {
       837  0
                   return true;
       838  
               }
       839  0
               return false;
       840  
           }
       841  
       
       842  
           /**
       843  
            * Returns a reference to the current project. This method is used instead
       844  
            * of auto-binding the project via component annotation in concrete
       845  
            * implementations of this. If the child has a
       846  
            * <code>@Component MavenProject project;</code> defined then the abstract
       847  
            * class (i.e. this class) will not have access to the current project (just
       848  
            * the way Maven works with the binding).
       849  
            *
       850  
            * @return returns a reference to the current project
       851  
            */
       852  
           protected MavenProject getProject() {
       853  0
               return project;
       854  
           }
       855  
       
       856  
           /**
       857  
            * Returns the list of Maven Projects in this build.
       858  
            *
       859  
            * @return the list of Maven Projects in this build
       860  
            */
       861  
           protected List<MavenProject> getReactorProjects() {
       862  0
               return reactorProjects;
       863  
           }
       864  
       
       865  
           /**
       866  
            * Returns the report format.
       867  
            *
       868  
            * @return the report format
       869  
            */
       870  
           protected String getFormat() {
       871  0
               return format;
       872  
           }
       873  
       
       874  
           /**
       875  
            * Generates the reports for a given dependency-check engine.
       876  
            *
       877  
            * @param engine a dependency-check engine
       878  
            * @param p the maven project
       879  
            * @param outputDir the directory path to write the report(s).
       880  
            */
       881  
           protected void writeReports(Engine engine, MavenProject p, File outputDir) {
       882  0
               DatabaseProperties prop = null;
       883  0
               CveDB cve = null;
       884  
               try {
       885  0
                   cve = new CveDB();
       886  0
                   cve.open();
       887  0
                   prop = cve.getDatabaseProperties();
       888  0
               } catch (DatabaseException ex) {
       889  0
                   if (getLog().isDebugEnabled()) {
       890  0
                       getLog().debug("Unable to retrieve DB Properties", ex);
       891  
                   }
       892  
               } finally {
       893  0
                   if (cve != null) {
       894  0
                       cve.close();
       895  
                   }
       896  
               }
       897  0
               final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop);
       898  
               try {
       899  0
                   r.generateReports(outputDir.getAbsolutePath(), format);
       900  0
               } catch (IOException ex) {
       901  0
                   getLog().error(
       902  
                           "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
       903  0
                   if (getLog().isDebugEnabled()) {
       904  0
                       getLog().debug("", ex);
       905  
                   }
       906  0
               } catch (Throwable ex) {
       907  0
                   getLog().error(
       908  
                           "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
       909  0
                   if (getLog().isDebugEnabled()) {
       910  0
                       getLog().debug("", ex);
       911  
                   }
       912  0
               }
       913  0
           }
       914  
       
       915  
           //<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary">
       916  
           /**
       917  
            * Checks to see if a vulnerability has been identified with a CVSS score
       918  
            * that is above the threshold set in the configuration.
       919  
            *
       920  
            * @param dependencies the list of dependency objects
       921  
            * @throws MojoFailureException thrown if a CVSS score is found that is
       922  
            * higher then the threshold set
       923  
            */
       924  
           protected void checkForFailure(List<Dependency> dependencies) throws MojoFailureException {
       925  0
               if (failBuildOnCVSS <= 10) {
       926  0
                   final StringBuilder ids = new StringBuilder();
       927  0
                   for (Dependency d : dependencies) {
       928  0
                       boolean addName = true;
       929  0
                       for (Vulnerability v : d.getVulnerabilities()) {
       930  0
                           if (v.getCvssScore() >= failBuildOnCVSS) {
       931  0
                               if (addName) {
       932  0
                                   addName = false;
       933  0
                                   ids.append(NEW_LINE).append(d.getFileName()).append(": ");
       934  0
                                   ids.append(v.getName());
       935  
                               } else {
       936  0
                                   ids.append(", ").append(v.getName());
       937  
                               }
       938  
                           }
       939  0
                           ids.append(v.getName());
       940  0
                       }
       941  0
                       if (ids.length() > 0) {
       942  0
                           summary.append(d.getFileName()).append(" (");
       943  0
                           firstEntry = true;
       944  0
                           for (Identifier id : d.getIdentifiers()) {
       945  0
                               if (firstEntry) {
       946  0
                                   firstEntry = false;
       939  0
                       }
       940  0
                   }
       941  0
                   if (ids.length() > 0) {
       942  0
                       final String msg = String.format("%n%nDependency-Check Failure:%n"
       943  
                               + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
       944  0
                               + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
       945  0
                       throw new MojoFailureException(msg);
       946  
                   }
       947  
                               } else {
       948  0
                                   summary.append(", ");
               }
       948  0
           }
       949  
                               }
       950  0
                               summary.append(id.getValue());
       951  0
                           }
       952  0
                           summary.append(") : ").append(ids).append(NEW_LINE);
       
       950  
           /**
       951  
            * Generates a warning message listing a summary of dependencies and their
       952  
            * associated CPE and CVE entries.
       953  
                       }
       954  0
                   }
       955  0
                   if (summary.length() > 0) {
       956  0
                       final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s"
       957  0
                               + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString());
       958  0
                       getLog().warn(msg);
       959  
                   }
       960  
               }
       961  0
           }
       962  
       
       963  
           //</editor-fold>
       964  
           //<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file">
       965  
           /**
            *
       954  
            * @param mp the Maven project for which the summary is shown
       955  
            * @param dependencies a list of dependency objects
       956  
            */
       957  
           protected void showSummary(MavenProject mp, List<Dependency> dependencies) {
       958  0
               if (showSummary) {
       959  0
                   final StringBuilder summary = new StringBuilder();
       960  0
                   for (Dependency d : dependencies) {
       961  0
                       boolean firstEntry = true;
       962  0
                       final StringBuilder ids = new StringBuilder();
       963  0
                       for (Vulnerability v : d.getVulnerabilities()) {
       964  0
                           if (firstEntry) {
       965  0
                               firstEntry = false;
       966  
            * Returns the key used to store the path to the data file that is saved by <code>writeDataFile()</code>. This key is used in
       967  
            * the <code>MavenProject.(set|get)ContextValue</code>.
                           } else {
       967  0
                               ids.append(", ");
       968  
            *
       969  
            * @return the key used to store the path to the data file
       970  
            */
       971  
           protected String getDataFileContextKey() {
       972  0
               return "dependency-check-path-" + dataFileName;
       973  
           }
       974  
       
       975  
           /**
       976  
            * Returns the key used to store the path to the output directory. When generating the report in the
                           }
       969  0
                           ids.append(v.getName());
       970  0
                       }
       971  0
                       if (ids.length() > 0) {
       972  0
                           summary.append(d.getFileName()).append(" (");
       973  0
                           firstEntry = true;
       974  0
                           for (Identifier id : d.getIdentifiers()) {
       975  0
                               if (firstEntry) {
       976  0
                                   firstEntry = false;
       977  
            * <code>executeAggregateReport()</code> the output directory should be obtained by using this key.
       978  
            *
                               } else {
       978  0
                                   summary.append(", ");
       979  
            * @return the key used to store the path to the output directory
       980  
            */
       981  
           protected String getOutputDirectoryContextKey() {
       982  0
               return "dependency-output-dir-" + dataFileName;
       983  
           }
       984  
       
       985  
           /**
       986  
            * Writes the scan data to disk. This is used to serialize the scan data between the "check" and "aggregate" phase.
       987  
            *
       988  
            * @param mp the mMven project for which the data file was created
       989  
            * @param writeTo the directory to write the data file
       990  
            * @param dependencies the list of dependencies to serialize
       991  
            */
       992  
           protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) {
       993  
               File file;
       994  
               //check to see if this was already written out
       995  0
               if (mp.getContextValue(this.getDataFileContextKey()) == null) {
       996  0
                   if (writeTo == null) {
       997  0
                       file = new File(mp.getBuild().getDirectory());
       998  0
                       file = new File(file, dataFileName);
       999  
                   } else {
       1000  0
                       file = new File(writeTo, dataFileName);
       1001  
                   }
       1002  0
                   final File parent = file.getParentFile();
       1003  0
                   if (!parent.isDirectory() && parent.mkdirs()) {
       1004  0
                       getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.",
       1005  0
                               parent.getAbsolutePath()));
       1006  
                   }
       1007  
       
       1008  0
                   ObjectOutputStream out = null;
       1009  
                   try {
       1010  0
                       if (dependencies != null) {
       1011  0
                           out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
       1012  0
                           out.writeObject(dependencies);
       1013  
                       }
       1014  0
                       if (getLog().isDebugEnabled()) {
       1015  0
                           getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s",
       1016  0
                                   file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey()));
       1017  
                       }
       1018  0
                       mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath());
       1019  0
                   } catch (IOException ex) {
       1020  0
                       getLog().warn("Unable to create data file used for report aggregation; "
       1021  
                               + "if report aggregation is being used the results may be incomplete.");
       1022  0
                       if (getLog().isDebugEnabled()) {
       1023  0
                           getLog().debug(ex.getMessage(), ex);
       1024  
                       }
       1025  
                   } finally {
       1026  0
                       if (out != null) {
       1027  
                           try {
       1028  0
                               out.close();
       1029  0
                           } catch (IOException ex) {
       1030  0
                               if (getLog().isDebugEnabled()) {
       1031  0
                                   getLog().debug("ignore", ex);
       1032  
                               }
       1033  0
                           }
       1034  
       980  0
                               summary.append(id.getValue());
       981  0
                           }
       982  0
                           summary.append(") : ").append(ids).append(NEW_LINE);
       983  
                       }
       1035  
       984  0
                   }
       985  0
                   if (summary.length() > 0) {
       986  0
                       final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s"
       987  0
                               + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString());
       988  0
                       getLog().warn(msg);
       989  
                   }
       1036  
       990  
               }
       1037  0
           }
       1038  
       991  0
           }
       992  
       
       1039  
           /**
       1040  
            * Reads the serialized scan data from disk. This is used to serialize the scan data between the "check" and "aggregate"
       1041  
            * phase.
       1042  
            *
       1043  
            * @param project the Maven project to read the data file from
       1044  
            * @return a <code>Engine</code> object populated with dependencies if the serialized data file exists; otherwise
       1045  
            * <code>null</code> is returned
       1046  
            */
       1047  
           protected List<Dependency> readDataFile(MavenProject project) {
       1048  0
               final Object oPath = project.getContextValue(this.getDataFileContextKey());
       1049  0
               if (oPath == null) {
       1050  0
                   return null;
       1051  
               }
       1052  0
               List<Dependency> ret = null;
       1053  0
               final String path = (String) oPath;
       1054  
               //ObjectInputStream ois = null;
       1055  0
               ExpectedOjectInputStream ois = null;
       1056  
               try {
       1057  
                   //ois = new ObjectInputStream(new FileInputStream(path));
       1058  0
                   ois = new ExpectedOjectInputStream(new FileInputStream(path),
       1059  
                           "java.util.ArrayList",
       1060  
                           "java.util.HashSet",
       1061  
                           "java.util.TreeSet",
       1062  
                           "java.lang.AbstractSet",
       1063  
                           "java.lang.AbstractCollection",
       1064  
                           "java.lang.Enum",
       1065  
                           "org.owasp.dependencycheck.dependency.Confidence",
       1066  
                           "org.owasp.dependencycheck.dependency.Dependency",
       1067  
                           "org.owasp.dependencycheck.dependency.Evidence",
       1068  
                           "org.owasp.dependencycheck.dependency.EvidenceCollection",
       1069  
                           "org.owasp.dependencycheck.dependency.Identifier",
       1070  
                           "org.owasp.dependencycheck.dependency.Reference",
       1071  
                           "org.owasp.dependencycheck.dependency.Vulnerability",
       1072  
                           "org.owasp.dependencycheck.dependency.VulnerabilityComparator",
       1073  
                           "org.owasp.dependencycheck.dependency.VulnerableSoftware",
       1074  
                           "org.owasp.dependencycheck.data.cpe.IndexEntry");
       1075  0
                   ret = (List<Dependency>) ois.readObject();
       1076  0
               } catch (FileNotFoundException ex) {
       1077  
                   //TODO fix logging
       1078  0
                   getLog().error("", ex);
       1079  0
               } catch (IOException ex) {
       1080  0
                   getLog().error("", ex);
       1081  0
               } catch (ClassNotFoundException ex) {
       1082  0
                   getLog().error("", ex);
       1083  
               } finally {
       1084  0
                   if (ois != null) {
       1085  
                       try {
       1086  0
                           ois.close();
       1087  0
                       } catch (IOException ex) {
       1088  0
                           getLog().error("", ex);
       1089  0
                       }
       1090  
                   }
       1091  
               }
       1092  0
               return ret;
       1093  
           }
       1094  
       993  
           //</editor-fold>
       994  
           //<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file">
       995  
           /**
       996  
            * Returns the key used to store the path to the data file that is saved by
       997  
            * <code>writeDataFile()</code>. This key is used in the
       998  
            * <code>MavenProject.(set|get)ContextValue</code>.
       999  
            *
       1000  
            * @return the key used to store the path to the data file
       1001  
            */
       1002  
           protected String getDataFileContextKey() {
       1003  0
               return "dependency-check-path-" + dataFileName;
       1004  
           }
       1005  
       
       1006  
           /**
       1007  
            * Returns the key used to store the path to the output directory. When
       1008  
            * generating the report in the <code>executeAggregateReport()</code> the
       1009  
            * output directory should be obtained by using this key.
       1010  
            *
       1011  
            * @return the key used to store the path to the output directory
       1012  
            */
       1013  
           protected String getOutputDirectoryContextKey() {
       1014  0
               return "dependency-output-dir-" + dataFileName;
       1015  
           }
       1016  
       
       1017  
           /**
       1018  
            * Writes the scan data to disk. This is used to serialize the scan data
       1019  
            * between the "check" and "aggregate" phase.
       1020  
            *
       1021  
            * @param mp the mMven project for which the data file was created
       1022  
            * @param writeTo the directory to write the data file
       1023  
            * @param dependencies the list of dependencies to serialize
       1024  
            */
       1025  
           protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) {
       1026  
               File file;
       1027  
               //check to see if this was already written out
       1028  0
               if (mp.getContextValue(this.getDataFileContextKey()) == null) {
       1029  0
                   if (writeTo == null) {
       1030  0
                       file = new File(mp.getBuild().getDirectory());
       1031  0
                       file = new File(file, dataFileName);
       1032  
                   } else {
       1033  0
                       file = new File(writeTo, dataFileName);
       1034  
                   }
       1035  0
                   final File parent = file.getParentFile();
       1036  0
                   if (!parent.isDirectory() && !parent.mkdirs()) {
       1037  0
                       getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.",
       1038  0
                               parent.getAbsolutePath()));
       1039  
                   }
       1040  
       
       1041  0
                   ObjectOutputStream out = null;
       1042  
                   try {
       1043  0
                       if (dependencies != null) {
       1044  0
                           out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
       1045  0
                           out.writeObject(dependencies);
       1046  
                       }
       1047  0
                       if (getLog().isDebugEnabled()) {
       1048  0
                           getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s",
       1049  0
                                   file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey()));
       1050  
                       }
       1051  0
                       mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath());
       1052  0
                   } catch (IOException ex) {
       1053  0
                       getLog().warn("Unable to create data file used for report aggregation; "
       1054  
                               + "if report aggregation is being used the results may be incomplete.");
       1055  0
                       if (getLog().isDebugEnabled()) {
       1056  0
                           getLog().debug(ex.getMessage(), ex);
       1057  
                       }
       1058  
                   } finally {
       1059  0
                       if (out != null) {
       1060  
                           try {
       1061  0
                               out.close();
       1062  0
                           } catch (IOException ex) {
       1063  0
                               if (getLog().isDebugEnabled()) {
       1064  0
                                   getLog().debug("ignore", ex);
       1065  
                               }
       1066  0
                           }
       1067  
                       }
       1068  
                   }
       1069  
               }
       1070  0
           }
       1071  
       
       1072  
           /**
       1073  
            * Reads the serialized scan data from disk. This is used to serialize the
       1074  
            * scan data between the "check" and "aggregate" phase.
       1075  
            *
       1076  
            * @param project the Maven project to read the data file from
       1077  
            * @return a <code>Engine</code> object populated with dependencies if the
       1078  
            * serialized data file exists; otherwise <code>null</code> is returned
       1079  
            */
       1080  
           protected List<Dependency> readDataFile(MavenProject project) {
       1081  0
               final Object oPath = project.getContextValue(this.getDataFileContextKey());
       1082  0
               if (oPath == null) {
       1083  0
                   return null;
       1084  
               }
       1085  0
               List<Dependency> ret = null;
       1086  0
               final String path = (String) oPath;
       1087  
               //ObjectInputStream ois = null;
       1088  0
               ExpectedOjectInputStream ois = null;
       1089  
               try {
       1090  
                   //ois = new ObjectInputStream(new FileInputStream(path));
       1091  0
                   ois = new ExpectedOjectInputStream(new FileInputStream(path),
       1092  
                           "java.util.ArrayList",
       1093  
                           "java.util.HashSet",
       1094  
                           "java.util.TreeSet",
       1095  
                           "java.lang.AbstractSet",
       1096  
                           "java.lang.AbstractCollection",
       1097  
                           "java.lang.Enum",
       1098  
                           "org.owasp.dependencycheck.dependency.Confidence",
       1099  
                           "org.owasp.dependencycheck.dependency.Dependency",
       1100  
                           "org.owasp.dependencycheck.dependency.Evidence",
       1101  
                           "org.owasp.dependencycheck.dependency.EvidenceCollection",
       1102  
                           "org.owasp.dependencycheck.dependency.Identifier",
       1103  
                           "org.owasp.dependencycheck.dependency.Reference",
       1104  
                           "org.owasp.dependencycheck.dependency.Vulnerability",
       1105  
                           "org.owasp.dependencycheck.dependency.VulnerabilityComparator",
       1106  
                           "org.owasp.dependencycheck.dependency.VulnerableSoftware",
       1107  
                           "org.owasp.dependencycheck.data.cpe.IndexEntry");
       1108  
                   @SuppressWarnings("unchecked")
       1109  0
                   final List<Dependency> depList = (List<Dependency>) ois.readObject();
       1110  0
                   ret = depList;
       1111  0
               } catch (FileNotFoundException ex) {
       1112  
                   //TODO fix logging
       1113  0
                   getLog().error("", ex);
       1114  0
               } catch (IOException ex) {
       1115  0
                   getLog().error("", ex);
       1116  0
               } catch (ClassNotFoundException ex) {
       1117  0
                   getLog().error("", ex);
       1118  
               } finally {
       1119  0
                   if (ois != null) {
       1120  
                       try {
       1121  0
                           ois.close();
       1122  0
                       } catch (IOException ex) {
       1123  0
                           getLog().error("", ex);
       1124  0
                       }
       1125  
                   }
       1126  
               }
       1127  0
               return ret;
       1128  
           }
       1129  
           //</editor-fold>
       1130  
       }
      - + diff --git a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.CheckMojo.html b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.CheckMojo.html index 79d2e285b..042d4083c 100644 --- a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.CheckMojo.html +++ b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.CheckMojo.html @@ -237,6 +237,6 @@
       }
      - + diff --git a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.Engine.html b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.Engine.html index 7ddd8fbc2..d0580428f 100644 --- a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.Engine.html +++ b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.Engine.html @@ -403,6 +403,6 @@
       }
      - + diff --git a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.HelpMojo.html b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.HelpMojo.html index af80e1d02..1337dde6a 100644 --- a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.HelpMojo.html +++ b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.HelpMojo.html @@ -770,6 +770,6 @@
       }
      - + diff --git a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.PurgeMojo.html b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.PurgeMojo.html index 931f06e56..a9172ce52 100644 --- a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.PurgeMojo.html +++ b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.PurgeMojo.html @@ -217,6 +217,6 @@
       }
      - + diff --git a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.UpdateMojo.html b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.UpdateMojo.html index 65f061717..47e415bbd 100644 --- a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.UpdateMojo.html +++ b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.UpdateMojo.html @@ -199,6 +199,6 @@
       }
      - + diff --git a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerAdapter.html b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerAdapter.html index 0aea169e5..2fe440c29 100644 --- a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerAdapter.html +++ b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerAdapter.html @@ -99,9 +99,9 @@
            */
       41  
           public MavenLoggerAdapter(Log log) {
      -  42  1
               super();
      -  43  1
               this.log = log;
      -  44  1
           }
      +  42  2
               super();
      +  43  2
               this.log = log;
      +  44  2
           }
       45  
       
       46   @@ -131,14 +131,14 @@
           @Override
       60  
           public void trace(String msg) {
      -  61  2
               if (log != null) {
      +  61  4
               if (log != null) {
       62  0
                   log.debug(msg);
       63  
               } else {
      -  64  2
                   System.out.println(msg);
      +  64  4
                   System.out.println(msg);
       65  
               }
      -  66  2
           }
      +  66  4
           }
       67  
       
       68   @@ -205,11 +205,11 @@
           @Override
       109  
           public boolean isDebugEnabled() {
      -  110  2
               if (log != null) {
      +  110  4
               if (log != null) {
       111  0
                   return log.isDebugEnabled();
       112  
               }
      -  113  2
               return true;
      +  113  4
               return true;
       114  
           }
       115   @@ -218,14 +218,14 @@
           @Override
       117  
           public void debug(String msg) {
      -  118  6
               if (log != null) {
      +  118  12
               if (log != null) {
       119  0
                   log.debug(msg);
       120  
               } else {
      -  121  6
                   System.out.println(msg);
      +  121  12
                   System.out.println(msg);
       122  
               }
      -  123  6
           }
      +  123  12
           }
       124  
       
       125   @@ -551,6 +551,6 @@
       }
      - + diff --git a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerFactory.html b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerFactory.html index 78de21b5c..69fe103bb 100644 --- a/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerFactory.html +++ b/dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerFactory.html @@ -99,9 +99,9 @@
            */
       41  
           public MavenLoggerFactory(Log log) {
      -  42  1
               super();
      -  43  1
               this.mavenLoggerAdapter = new MavenLoggerAdapter(log);
      -  44  1
           }
      +  42  2
               super();
      +  43  2
               this.mavenLoggerAdapter = new MavenLoggerAdapter(log);
      +  44  2
           }
       45  
       
       46   @@ -120,13 +120,13 @@
           @Override
       53  
           public Logger getLogger(String name) {
      -  54  3
               return mavenLoggerAdapter;
      +  54  6
               return mavenLoggerAdapter;
       55  
           }
       56  
       }
      - + diff --git a/dependency-check-maven/cobertura/org.slf4j.impl.StaticLoggerBinder.html b/dependency-check-maven/cobertura/org.slf4j.impl.StaticLoggerBinder.html index 55884c53f..0b4a10937 100644 --- a/dependency-check-maven/cobertura/org.slf4j.impl.StaticLoggerBinder.html +++ b/dependency-check-maven/cobertura/org.slf4j.impl.StaticLoggerBinder.html @@ -68,166 +68,170 @@  25  
       /**
       26   -
        * The binding of org.slf4j.LoggerFactory class with an actual instance of org.slf4j.ILoggerFactory is performed using information
      +
        * The binding of org.slf4j.LoggerFactory class with an actual instance of
       27   -
        * returned by this class.
      +
        * org.slf4j.ILoggerFactory is performed using information returned by this
       28   -
        *
      +
        * class.
       29   -
        * @author colezlaw
      +
        *
       30   -
        */
      +
        * @author colezlaw
       31   -
       //CSOFF: FinalClass
      +
        */
       32   -
       public class StaticLoggerBinder implements LoggerFactoryBinder {
      +
       //CSOFF: FinalClass
       33   -
       //CSON: FinalClass
      +
       public class StaticLoggerBinder implements LoggerFactoryBinder {
       34   -
       
      +
       //CSON: FinalClass
       35   -
           /**
      +
       
       36   -
            * The unique instance of this class
      +
           /**
       37   +
            * The unique instance of this class
      +  38  
            */
      -  38  1
           private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
      -  39   -
       
      +  39  2
           private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
       40   -
           /**
      +
       
       41   -
            * Return the singleton of this class.
      +
           /**
       42   -
            *
      +
            * Return the singleton of this class.
       43   -
            * @return the StaticLoggerBinder singleton
      +
            *
       44   -
            */
      +
            * @return the StaticLoggerBinder singleton
       45   +
            */
      +  46  
           public static final StaticLoggerBinder getSingleton() {
      -  46  5
               return SINGLETON;
      -  47   -
           }
      +  47  10
               return SINGLETON;
       48   -
       
      +
           }
       49   -
           /**
      +
       
       50   -
            * Maven mojos have their own logger, so we'll use one of those
      +
           /**
       51   +
            * Maven mojos have their own logger, so we'll use one of those.
      +  52  
            */
      -  52  1
           private Log log = null;
      -  53   -
       
      +  53  2
           private Log log = null;
       54   -
           /**
      +
       
       55   -
            * Set the Task which will this is to log through.
      +
           /**
       56   -
            *
      +
            * Set the Task which will this is to log through.
       57   -
            * @param log the task through which to log
      +
            *
       58   -
            */
      +
            * @param log the task through which to log
       59   +
            */
      +  60  
           public void setLog(Log log) {
      -  60  0
               this.log = log;
      -  61  0
               loggerFactory = new MavenLoggerFactory(log);
      -  62  0
           }
      -  63   -
       
      +  61  0
               this.log = log;
      +  62  0
               loggerFactory = new MavenLoggerFactory(log);
      +  63  0
           }
       64   -
           /**
      +
       
       65   -
            * Declare the version of the SLF4J API this implementation is compiled against. The value of this filed is usually modified
      +
           /**
       66   -
            * with each release.
      +
            * Declare the version of the SLF4J API this implementation is compiled
       67   -
            */
      +
            * against. The value of this filed is usually modified with each release.
       68   -
           // to avoid constant folding by the compiler, this field must *not* be final
      +
            */
       69   -
           //CSOFF: StaticVariableName
      +
           // to avoid constant folding by the compiler, this field must *not* be final
       70   +
           //CSOFF: StaticVariableName
      +  71  
           //CSOFF: VisibilityModifier
      -  71  1
           public static String REQUESTED_API_VERSION = "1.7.12"; // final
      -  72   -
           //CSON: VisibilityModifier
      +  72  2
           public static String REQUESTED_API_VERSION = "1.7.12"; // final
       73   -
           //CSON: StaticVariableName
      +
           //CSON: VisibilityModifier
       74   -
       
      +
           //CSON: StaticVariableName
       75   -
           /**
      +
       
       76   -
            * The logger factory class string.
      +
           /**
       77   +
            * The logger factory class string.
      +  78  
            */
      -  78  1
           private static final String LOGGER_FACTORY_CLASS = MavenLoggerFactory.class.getName();
      -  79   -
       
      +  79  2
           private static final String LOGGER_FACTORY_CLASS = MavenLoggerFactory.class.getName();
       80   -
           /**
      +
       
       81   -
            * The ILoggerFactory instance returned by the {@link #getLoggerFactory} method should always be the same object
      +
           /**
       82   -
            */
      +
            * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
       83   -
           private ILoggerFactory loggerFactory;
      +
            * method should always be the same object
       84   -
       
      +
            */
       85   -
           /**
      +
           private ILoggerFactory loggerFactory;
       86   -
            * Constructs the static logger factory.
      +
       
       87   -
            */
      -  88  1
           private StaticLoggerBinder() {
      -  89  1
               loggerFactory = new MavenLoggerFactory(log);
      -  90  1
           }
      -  91   -
       
      -  92  
           /**
      +  88   +
            * Constructs the static logger factory.
      +  89   +
            */
      +  90  2
           private StaticLoggerBinder() {
      +  91  2
               loggerFactory = new MavenLoggerFactory(log);
      +  92  2
           }
       93   -
            * Returns the logger factory.
      -  94   -
            *
      -  95   -
            * @return the logger factory
      -  96   -
            */
      -  97   -
           @Override
      -  98   -
           public ILoggerFactory getLoggerFactory() {
      -  99  3
               return loggerFactory;
      -  100   -
           }
      -  101  
       
      -  102   +  94  
           /**
      -  103   -
            * Returns the logger factory class string.
      -  104   +  95   +
            * Returns the logger factory.
      +  96  
            *
      -  105   -
            * @return the logger factory class string
      -  106   +  97   +
            * @return the logger factory
      +  98  
            */
      -  107   +  99  
           @Override
      -  108   -
           public String getLoggerFactoryClassStr() {
      -  109  1
               return LOGGER_FACTORY_CLASS;
      -  110   +  100   +
           public ILoggerFactory getLoggerFactory() {
      +  101  6
               return loggerFactory;
      +  102  
           }
      -  111   +  103   +
       
      +  104   +
           /**
      +  105   +
            * Returns the logger factory class string.
      +  106   +
            *
      +  107   +
            * @return the logger factory class string
      +  108   +
            */
      +  109   +
           @Override
      +  110   +
           public String getLoggerFactoryClassStr() {
      +  111  2
               return LOGGER_FACTORY_CLASS;
      +  112   +
           }
      +  113  
       }
      - + diff --git a/dependency-check-maven/configuration.html b/dependency-check-maven/configuration.html index 8f4400fbb..0185a159d 100644 --- a/dependency-check-maven/configuration.html +++ b/dependency-check-maven/configuration.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Goals @@ -52,7 +52,7 @@ @@ -136,9 +136,6 @@ developed using - - - built on cloudbees @@ -274,7 +271,7 @@ skipTestScope -Should be skip analysis for artifacts with Test Scope +Skip analysis for artifacts with Test Scope true @@ -283,7 +280,7 @@ skipProvidedScope -Should be skip analysis for artifacts with Provided Scope +Skip analysis for artifacts with Provided Scope false @@ -292,7 +289,7 @@ skipRuntimeScope -Should be skip analysis for artifacts with Runtime Scope +Skip analysis for artifacts with Runtime Scope false @@ -305,6 +302,15 @@   + + + +enableExperimental + +Enable the experimental analyzers. If not enabled the experimental analyzers (see below) will not be loaded or used. + +false +

      Analyzer Configuration

      @@ -391,7 +397,7 @@ pyDistributionAnalyzerEnabled -Sets whether the Python Distribution Analyzer will be used. +Sets whether the experimental Python Distribution Analyzer will be used. true @@ -400,7 +406,7 @@ pyPackageAnalyzerEnabled -Sets whether the Python Package Analyzer will be used. +Sets whether the experimental Python Package Analyzer will be used. true @@ -409,7 +415,7 @@ rubygemsAnalyzerEnabled -Sets whether the Ruby Gemspec Analyzer will be used. +Sets whether the experimental Ruby Gemspec Analyzer will be used. true @@ -418,7 +424,7 @@ opensslAnalyzerEnabled -Sets whether or not the openssl Analyzer should be used. +Sets whether the openssl Analyzer should be used. true @@ -427,7 +433,7 @@ cmakeAnalyzerEnabled -Sets whether or not the CMake Analyzer should be used. +Sets whether the experimental CMake Analyzer should be used. true @@ -436,7 +442,7 @@ autoconfAnalyzerEnabled -Sets whether or not the autoconf Analyzer should be used. +Sets whether the experimental autoconf Analyzer should be used. true @@ -445,7 +451,7 @@ composerAnalyzerEnabled -Sets whether or not the PHP Composer Lock File Analyzer should be used. +Sets whether the experimental PHP Composer Lock File Analyzer should be used. true @@ -454,7 +460,7 @@ nodeAnalyzerEnabled -Sets whether or not the Node.js Analyzer should be used. +Sets whether the experimental Node.js Analyzer should be used. true @@ -463,7 +469,7 @@ nuspecAnalyzerEnabled -Sets whether or not the .NET Nuget Nuspec Analyzer will be used. +Sets whether the .NET Nuget Nuspec Analyzer will be used. true @@ -472,7 +478,7 @@ assemblyAnalyzerEnabled -Sets whether or not the .NET Assembly Analyzer should be used. +Sets whether the .NET Assembly Analyzer should be used. true @@ -623,7 +629,7 @@

      Proxy Configuration

      -

      Use Maven’s settings to configure a proxy server. If multiple proxies are configured in the Maven settings file you must tell dependency-check which proxy to use with the following property:

      +

      Use Maven’s settings to configure a proxy server. Please see the dependency-check proxy configuration page for additional problem solving techniques. If multiple proxies are configured in the Maven settings file you must tell dependency-check which proxy to use with the following property:

      diff --git a/dependency-check-maven/dependency-analysis.html b/dependency-check-maven/dependency-analysis.html index 90895a39f..c085d6726 100644 --- a/dependency-check-maven/dependency-analysis.html +++ b/dependency-check-maven/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Dependencies Report @@ -52,7 +52,7 @@ @@ -229,9 +229,6 @@ developed using - - - built on cloudbees @@ -256,7 +253,7 @@ - + @@ -264,7 +261,7 @@ - + @@ -272,7 +269,7 @@ - + @@ -280,7 +277,7 @@ - + @@ -288,7 +285,7 @@ - + @@ -361,6 +358,14 @@ + + + + + + + + @@ -368,18 +373,10 @@ - - - - - - - - - + diff --git a/dependency-check-maven/dependency-updates-report.html b/dependency-check-maven/dependency-updates-report.html index a091a3ea1..a37aa2efe 100644 --- a/dependency-check-maven/dependency-updates-report.html +++ b/dependency-check-maven/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Dependency Updates Report @@ -52,7 +52,7 @@ @@ -229,9 +229,6 @@ developed using - - - built on cloudbees @@ -247,7 +244,7 @@ - + @@ -255,11 +252,11 @@ - + - + @@ -367,7 +364,7 @@ - + @@ -391,7 +388,7 @@ - + @@ -403,7 +400,7 @@ - + @@ -484,39 +481,39 @@ - + - + - + - + - + - + - + - + - + @@ -592,7 +589,7 @@ - + @@ -601,18 +598,18 @@ - + - + - + - + @@ -682,7 +679,7 @@ - + @@ -694,7 +691,7 @@ - + @@ -815,7 +812,7 @@ -
      org.owasp dependency-check-core1.3.61.4.0 compile jar
      org.owasp dependency-check-utils1.3.61.4.0 compile jar
      org.apache.maven maven-plugin-api3.3.33.3.9 provided jar
      org.apache.maven maven-settings3.3.33.3.9 provided jar
      org.apache.maven maven-core3.3.33.3.9 provided jarjar false
      org.apache.mavenmaven-model3.3.9providedjarfalse
      org.apache.maven.doxia doxia-sink-api 1.0 jar false
      org.apache.mavenmaven-model3.3.3providedjarfalse
      org.apache.maven maven-artifact3.3.33.3.9 provided jar
      # of dependencies using the latest version available23
      24
      # of dependencies where the next version available is smaller than an incremental version update
      # of dependencies where the next version available is an incremental version update3
      1
      # of dependencies where the next version available is a minor version update6
      7
      # of dependencies where the next version available is a major version update commons-io commons-io2.42.5 jar org.apache.ant ant1.9.61.9.7 jar org.apache.ant ant-testutil1.9.61.9.7 jar4.8.0 5.0.0
      org.apache.maven maven-core3.3.33.3.9 jar 3.3.9
      org.apache.maven maven-plugin-api3.3.33.3.9 jar 3.3.9
      org.apache.maven maven-settings3.3.33.3.9 jar 3.3.9
      org.jmockit jmockit 1.22jar 1.23
      org.jsoup jsoup1.8.31.9.1 jar 1.9.2
      org.owasp dependency-check-core1.3.61.4.0 compile jar org.owasp dependency-check-utils1.3.61.4.0 compile jarjar
      Newer versions1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191 Latest Minor
      +1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191
      1.4.192 Latest Minor

      com.sun.mail:mailapi

      @@ -905,7 +902,7 @@ - + @@ -953,7 +950,7 @@ - + @@ -977,7 +974,7 @@ - + @@ -1064,7 +1061,7 @@ -
      commons-io
      Current Version2.4
      2.5
      Scope
      ant
      Current Version1.9.6
      1.9.7
      Scope
      ant-testutil
      Current Version1.9.6
      1.9.7
      Scope
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-core

      @@ -1091,7 +1088,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1118,7 +1115,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1145,13 +1142,13 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.maven:maven-core

      - + @@ -1160,7 +1157,7 @@ - + @@ -1169,16 +1166,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-core
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-plugin-api

      - + @@ -1187,7 +1181,7 @@ - + @@ -1196,16 +1190,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-plugin-api
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-settings

      - + @@ -1214,7 +1205,7 @@ - + @@ -1223,10 +1214,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-settings
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven.plugin-testing:maven-plugin-testing-harness

      @@ -1376,7 +1364,7 @@
      - + @@ -1394,13 +1382,16 @@ -
      Status No newer versions available.
       There is at least one newer minor version available. Minor updates are sometimes passive.
      Group Id org.jmockit
      Typejar
      +jar + +Newer versions +1.23 Next Minor
      1.24 Latest Minor

      org.jsoup:jsoup

      - + @@ -1409,7 +1400,7 @@ - + @@ -1418,7 +1409,10 @@ -
      Status No newer versions available.
       There is at least one newer incremental version available. Incremental updates are typically passive.
      Group Id org.jsoup
      jsoup
      Current Version1.8.3
      1.9.1
      Scope
      Typejar
      +jar + +Newer versions +1.9.2 Next Incremental

      org.owasp:dependency-check-core

      @@ -1433,7 +1427,7 @@ - + @@ -1457,7 +1451,7 @@ - + diff --git a/dependency-check-maven/findbugs.html b/dependency-check-maven/findbugs.html index 82096de33..7c0b90a98 100644 --- a/dependency-check-maven/findbugs.html +++ b/dependency-check-maven/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-maven – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ @@ -229,9 +229,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-maven/help-mojo.html b/dependency-check-maven/help-mojo.html index 8d6b7c4f1..46fe99e45 100644 --- a/dependency-check-maven/help-mojo.html +++ b/dependency-check-maven/help-mojo.html @@ -1,13 +1,13 @@ - + dependency-check-maven – dependency-check:help @@ -52,7 +52,7 @@ @@ -138,9 +138,6 @@ developed using - - - built on cloudbees @@ -156,7 +153,7 @@

      Full name:

      -

      org.owasp:dependency-check-maven:1.3.6:help

      +

      org.owasp:dependency-check-maven:1.4.0:help

      Description:

      diff --git a/dependency-check-maven/index.html b/dependency-check-maven/index.html index 6bb768c64..cba904a4f 100644 --- a/dependency-check-maven/index.html +++ b/dependency-check-maven/index.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Usage @@ -52,7 +52,7 @@ @@ -136,9 +136,6 @@ developed using - - - built on cloudbees @@ -166,7 +163,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.3.6</version> + <version>1.4.0</version> <executions> <execution> <goals> @@ -197,7 +194,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.3.6</version> + <version>1.4.0</version> <reportSets> <reportSet> <reports> @@ -228,7 +225,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.3.6</version> + <version>1.4.0</version> <configuration> <failBuildOnCVSS>8</failBuildOnCVSS> </configuration> @@ -261,7 +258,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.3.6</version> + <version>1.4.0</version> <configuration> <skipProvidedScope>true</skipProvidedScope> <skipRuntimeScope>true</skipRuntimeScope> @@ -295,7 +292,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.3.6</version> + <version>1.4.0</version> <configuration> <cveUrl12Modified>http://internal-mirror.mycorp.com/downloads/nist/nvdcve-Modified.xml.gz</cveUrl12Modified> <cveUrl20Modified>http://internal-mirror.mycorp.com/downloads/nist/nvdcve-2.0-Modified.xml.gz</cveUrl20Modified> @@ -331,7 +328,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.3.6</version> + <version>1.4.0</version> <executions> <execution> <goals> diff --git a/dependency-check-maven/integration.html b/dependency-check-maven/integration.html index 19292b341..2e6dc57bf 100644 --- a/dependency-check-maven/integration.html +++ b/dependency-check-maven/integration.html @@ -1,13 +1,13 @@ - + dependency-check-maven – CI Management @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees @@ -200,11 +197,11 @@

      Overview

      -

      This project uses Continuous Integration System.

      +

      This project uses Travis CI.

      Access

      The following is a link to the continuous integration system used by the project:

      -
      +

      Notifiers

      No notifiers are defined. Please check back at a later date.

      diff --git a/dependency-check-maven/issue-tracking.html b/dependency-check-maven/issue-tracking.html index 275da4566..3418be32f 100644 --- a/dependency-check-maven/issue-tracking.html +++ b/dependency-check-maven/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Issue Management @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-maven/license.html b/dependency-check-maven/license.html index e71d7b29d..1edb451b5 100644 --- a/dependency-check-maven/license.html +++ b/dependency-check-maven/license.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Licenses @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-maven/mail-lists.html b/dependency-check-maven/mail-lists.html index c64c9d0d9..76806f7c3 100644 --- a/dependency-check-maven/mail-lists.html +++ b/dependency-check-maven/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Mailing Lists @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-maven/plugin-info.html b/dependency-check-maven/plugin-info.html index 2ebb16da8..a2f15e6ef 100644 --- a/dependency-check-maven/plugin-info.html +++ b/dependency-check-maven/plugin-info.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Plugin Documentation @@ -52,7 +52,7 @@ @@ -229,9 +229,6 @@ developed using - - - built on cloudbees @@ -302,7 +299,7 @@ have any known published vulnerabilities.
      dependency-check-core
      Current Version1.3.6
      1.4.0
      Scope compile
      dependency-check-utils
      Current Version1.3.6
      1.4.0
      Scope compile
      <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.3.6</version> + <version>1.4.0</version> </plugin> ... </plugins> @@ -312,7 +309,7 @@ have any known published vulnerabilities. <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.3.6</version> + <version>1.4.0</version> </plugin> ... </plugins> @@ -324,7 +321,7 @@ have any known published vulnerabilities. <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.3.6</version> + <version>1.4.0</version> </plugin> ... </plugins> diff --git a/dependency-check-maven/plugin-updates-report.html b/dependency-check-maven/plugin-updates-report.html index b7aafce5c..7cbff46e9 100644 --- a/dependency-check-maven/plugin-updates-report.html +++ b/dependency-check-maven/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Plugin Updates Report @@ -52,7 +52,7 @@ @@ -229,9 +229,6 @@ developed using - - - built on cloudbees
      @@ -247,7 +244,7 @@ # of plugins using the latest version available -20 +19 # of plugins where the next version available is smaller than an incremental version update @@ -263,7 +260,7 @@ # of plugins where the next version available is a major version update -0 +1 # of plugins where a dependencies section containes a dependency with an updated version @@ -385,7 +382,7 @@ org.apache.maven.plugins maven-jar-plugin -2.6 +3.0.0 @@ -415,7 +412,7 @@ org.apache.maven.plugins maven-resources-plugin -2.7 +3.0.0 @@ -425,21 +422,21 @@ org.apache.maven.plugins maven-site-plugin -3.5 +3.5.1 - + org.apache.maven.plugins maven-source-plugin -2.4 - +2.4 +3.0.0 @@ -681,7 +678,7 @@ maven-jar-plugin Current Version -2.6 +3.0.0

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -741,7 +738,7 @@ -
      maven-resources-plugin
      Current Version2.7
      +3.0.0

      Plugin org.apache.maven.plugins:maven-site-plugin

      @@ -756,13 +753,13 @@ -
      maven-site-plugin
      Current Version3.5
      +3.5.1

      Plugin org.apache.maven.plugins:maven-source-plugin

      - + @@ -771,7 +768,10 @@ -
      Status No newer versions available.
       There is at least one newer major version available. Major updates are rarely passive.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      +2.4 + +Newer versions +3.0.0 Next Major

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-maven/pmd.html b/dependency-check-maven/pmd.html index 162d8053d..0cf9011ef 100644 --- a/dependency-check-maven/pmd.html +++ b/dependency-check-maven/pmd.html @@ -1,13 +1,13 @@ - + dependency-check-maven – PMD Results @@ -52,7 +52,7 @@ @@ -229,9 +229,6 @@ developed using - - - built on cloudbees @@ -253,7 +250,7 @@ -
      Line
      Useless parentheses.737
      +761 diff --git a/dependency-check-maven/project-info.html b/dependency-check-maven/project-info.html index b1283d913..e8e36b725 100644 --- a/dependency-check-maven/project-info.html +++ b/dependency-check-maven/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Information @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-maven/project-reports.html b/dependency-check-maven/project-reports.html index 3285a51b6..27bc1006c 100644 --- a/dependency-check-maven/project-reports.html +++ b/dependency-check-maven/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Generated Reports @@ -52,7 +52,7 @@ @@ -229,9 +229,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-maven/project-summary.html b/dependency-check-maven/project-summary.html index 44496b672..dd0897cf5 100644 --- a/dependency-check-maven/project-summary.html +++ b/dependency-check-maven/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Summary @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees @@ -241,7 +238,7 @@ dependency-check-maven Version -1.3.6 +1.4.0 Type maven-plugin diff --git a/dependency-check-maven/purge-mojo.html b/dependency-check-maven/purge-mojo.html index 9d6f95761..7b5540450 100644 --- a/dependency-check-maven/purge-mojo.html +++ b/dependency-check-maven/purge-mojo.html @@ -1,13 +1,13 @@ - + dependency-check-maven – dependency-check:purge @@ -52,7 +52,7 @@ @@ -138,9 +138,6 @@ developed using - - - built on cloudbees @@ -158,7 +155,7 @@

      Full name:

      -

      org.owasp:dependency-check-maven:1.3.6:purge

      +

      org.owasp:dependency-check-maven:1.4.0:purge

      Description:

      @@ -494,6 +491,17 @@ duration in hours.
      User property is: cveValidForHours. +enableExperimental + +Boolean + +- + +Sets whether Experimental analyzers are enabled. Default is false.
      User property is: enableExperimental. + + + + externalReport String @@ -503,7 +511,7 @@ duration in hours.
      User property is: cveValidForHours. Deprecated. the internal report is no longer supported
      User property is: externalReport. - + jarAnalyzerEnabled @@ -514,7 +522,7 @@ duration in hours.
      User property is: cveValidForHours. Whether or not the Jar Analyzer is enabled.
      User property is: jarAnalyzerEnabled. - + mavenSettings @@ -525,7 +533,7 @@ duration in hours.
      User property is: cveValidForHours. The Maven settings.
      Default value is: ${settings}.
      User property is: mavenSettings. - + mavenSettingsProxyId @@ -536,7 +544,7 @@ duration in hours.
      User property is: cveValidForHours. The maven settings proxy id.
      User property is: mavenSettingsProxyId. - + nexusAnalyzerEnabled @@ -547,7 +555,7 @@ duration in hours.
      User property is: cveValidForHours. Whether or not the Nexus Analyzer is enabled.
      User property is: nexusAnalyzerEnabled. - + nexusUrl @@ -559,7 +567,7 @@ duration in hours.
      User property is: cveValidForHours. (http://domain/nexus/service/local).
      User property is: nexusUrl. - + nexusUsesProxy @@ -570,7 +578,7 @@ duration in hours.
      User property is: cveValidForHours. Whether or not the configured proxy is used to connect to Nexus.
      User property is: nexusUsesProxy. - + nodeAnalyzerEnabled @@ -581,7 +589,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether or not the Node.js Analyzer should be used.
      User property is: nodeAnalyzerEnabled. - + nuspecAnalyzerEnabled @@ -592,7 +600,7 @@ duration in hours.
      User property is: cveValidForHours. Whether or not the .NET Nuspec Analyzer is enabled.
      User property is: nuspecAnalyzerEnabled. - + opensslAnalyzerEnabled @@ -603,7 +611,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether or not the openssl Analyzer should be used.
      User property is: opensslAnalyzerEnabled. - + pathToMono @@ -614,7 +622,7 @@ duration in hours.
      User property is: cveValidForHours. The path to mono for .NET Assembly analysis on non-windows systems.
      User property is: pathToMono. - + proxyUrl @@ -625,7 +633,7 @@ duration in hours.
      User property is: cveValidForHours. Deprecated. Please use mavenSettings instead
      User property is: proxyUrl. - + pyDistributionAnalyzerEnabled @@ -636,7 +644,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether the Python Distribution Analyzer will be used.
      User property is: pyDistributionAnalyzerEnabled. - + pyPackageAnalyzerEnabled @@ -647,7 +655,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether the Python Package Analyzer will be used.
      User property is: pyPackageAnalyzerEnabled. - + rubygemsAnalyzerEnabled @@ -658,7 +666,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether the Ruby Gemspec Analyzer will be used.
      User property is: rubygemsAnalyzerEnabled. - + serverId @@ -670,7 +678,7 @@ duration in hours.
      User property is: cveValidForHours. passwords from the settings.xml.
      User property is: serverId. - + showSummary @@ -681,7 +689,7 @@ passwords from the settings.xml.
      User property is: serverId Flag indicating whether or not to show a summary in the output.
      Default value is: true.
      User property is: showSummary. - + skip @@ -692,7 +700,7 @@ passwords from the settings.xml.
      User property is: serverId Skip Dependency Check altogether.
      Default value is: false.
      User property is: dependency-check.skip. - + skipProvidedScope @@ -703,7 +711,7 @@ passwords from the settings.xml.
      User property is: serverId Skip Analysis for Provided Scope Dependencies.
      Default value is: false.
      User property is: skipProvidedScope. - + skipRuntimeScope @@ -714,7 +722,7 @@ passwords from the settings.xml.
      User property is: serverId Skip Analysis for Runtime Scope Dependencies.
      Default value is: false.
      User property is: skipRuntimeScope. - + skipTestScope @@ -725,7 +733,7 @@ passwords from the settings.xml.
      User property is: serverId Skip Analysis for Test Scope Dependencies.
      Default value is: true.
      User property is: skipTestScope. - + suppressionFile @@ -736,7 +744,7 @@ passwords from the settings.xml.
      User property is: serverId The path to the suppression file.
      User property is: suppressionFile. - + zipExtensions @@ -1012,6 +1020,18 @@ duration in hours.
    85. User Property: databaseUser

    86. +

      enableExperimental:

      + +
      Sets whether Experimental analyzers are enabled. Default is false.
      + +

      externalReport:

      Deprecated. the internal report is no longer supported
      diff --git a/dependency-check-maven/source-repository.html b/dependency-check-maven/source-repository.html index a10c7b83e..0a1a4c892 100644 --- a/dependency-check-maven/source-repository.html +++ b/dependency-check-maven/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Source Code Management @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-maven/surefire-report.html b/dependency-check-maven/surefire-report.html index 139f3b89d..7ca3cfd7f 100644 --- a/dependency-check-maven/surefire-report.html +++ b/dependency-check-maven/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Surefire Report @@ -52,7 +52,7 @@ @@ -229,9 +229,6 @@ developed using - - - built on cloudbees @@ -276,7 +273,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.447
      +0.756

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -297,7 +294,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.447
      +0.756

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.maven

      @@ -319,7 +316,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.447

      +0.756

      Test Cases

      [Summary] [Package List] [Test Cases]

      diff --git a/dependency-check-maven/taglist.html b/dependency-check-maven/taglist.html index 5c432ad83..03290eb36 100644 --- a/dependency-check-maven/taglist.html +++ b/dependency-check-maven/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Tag List report @@ -52,7 +52,7 @@ @@ -229,9 +229,6 @@ developed using - - - built on cloudbees
      @@ -262,7 +259,7 @@ Line fix logging -1077 +1112 org.owasp.dependencycheck.maven.BaseDependencyCheckMojoTest Line diff --git a/dependency-check-maven/team-list.html b/dependency-check-maven/team-list.html index f4ea78eee..972087c02 100644 --- a/dependency-check-maven/team-list.html +++ b/dependency-check-maven/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Team @@ -52,7 +52,7 @@ @@ -187,9 +187,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-maven/update-only-mojo.html b/dependency-check-maven/update-only-mojo.html index e060ad0ad..2fe281ffd 100644 --- a/dependency-check-maven/update-only-mojo.html +++ b/dependency-check-maven/update-only-mojo.html @@ -1,13 +1,13 @@ - + dependency-check-maven – dependency-check:update-only @@ -52,7 +52,7 @@ @@ -138,9 +138,6 @@ developed using - - - built on cloudbees @@ -158,7 +155,7 @@

      Full name:

      -

      org.owasp:dependency-check-maven:1.3.6:update-only

      +

      org.owasp:dependency-check-maven:1.4.0:update-only

      Description:

      @@ -495,6 +492,17 @@ duration in hours.
      User property is: cveValidForHours. +enableExperimental + +Boolean + +- + +Sets whether Experimental analyzers are enabled. Default is false.
      User property is: enableExperimental. + + + + externalReport String @@ -504,7 +512,7 @@ duration in hours.
      User property is: cveValidForHours. Deprecated. the internal report is no longer supported
      User property is: externalReport. - + jarAnalyzerEnabled @@ -515,7 +523,7 @@ duration in hours.
      User property is: cveValidForHours. Whether or not the Jar Analyzer is enabled.
      User property is: jarAnalyzerEnabled. - + mavenSettings @@ -526,7 +534,7 @@ duration in hours.
      User property is: cveValidForHours. The Maven settings.
      Default value is: ${settings}.
      User property is: mavenSettings. - + mavenSettingsProxyId @@ -537,7 +545,7 @@ duration in hours.
      User property is: cveValidForHours. The maven settings proxy id.
      User property is: mavenSettingsProxyId. - + nexusAnalyzerEnabled @@ -548,7 +556,7 @@ duration in hours.
      User property is: cveValidForHours. Whether or not the Nexus Analyzer is enabled.
      User property is: nexusAnalyzerEnabled. - + nexusUrl @@ -560,7 +568,7 @@ duration in hours.
      User property is: cveValidForHours. (http://domain/nexus/service/local).
      User property is: nexusUrl. - + nexusUsesProxy @@ -571,7 +579,7 @@ duration in hours.
      User property is: cveValidForHours. Whether or not the configured proxy is used to connect to Nexus.
      User property is: nexusUsesProxy. - + nodeAnalyzerEnabled @@ -582,7 +590,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether or not the Node.js Analyzer should be used.
      User property is: nodeAnalyzerEnabled. - + nuspecAnalyzerEnabled @@ -593,7 +601,7 @@ duration in hours.
      User property is: cveValidForHours. Whether or not the .NET Nuspec Analyzer is enabled.
      User property is: nuspecAnalyzerEnabled. - + opensslAnalyzerEnabled @@ -604,7 +612,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether or not the openssl Analyzer should be used.
      User property is: opensslAnalyzerEnabled. - + pathToMono @@ -615,7 +623,7 @@ duration in hours.
      User property is: cveValidForHours. The path to mono for .NET Assembly analysis on non-windows systems.
      User property is: pathToMono. - + proxyUrl @@ -626,7 +634,7 @@ duration in hours.
      User property is: cveValidForHours. Deprecated. Please use mavenSettings instead
      User property is: proxyUrl. - + pyDistributionAnalyzerEnabled @@ -637,7 +645,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether the Python Distribution Analyzer will be used.
      User property is: pyDistributionAnalyzerEnabled. - + pyPackageAnalyzerEnabled @@ -648,7 +656,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether the Python Package Analyzer will be used.
      User property is: pyPackageAnalyzerEnabled. - + rubygemsAnalyzerEnabled @@ -659,7 +667,7 @@ duration in hours.
      User property is: cveValidForHours. Sets whether the Ruby Gemspec Analyzer will be used.
      User property is: rubygemsAnalyzerEnabled. - + serverId @@ -671,7 +679,7 @@ duration in hours.
      User property is: cveValidForHours. passwords from the settings.xml.
      User property is: serverId. - + showSummary @@ -682,7 +690,7 @@ passwords from the settings.xml.
      User property is: serverId Flag indicating whether or not to show a summary in the output.
      Default value is: true.
      User property is: showSummary. - + skip @@ -693,7 +701,7 @@ passwords from the settings.xml.
      User property is: serverId Skip Dependency Check altogether.
      Default value is: false.
      User property is: dependency-check.skip. - + skipProvidedScope @@ -704,7 +712,7 @@ passwords from the settings.xml.
      User property is: serverId Skip Analysis for Provided Scope Dependencies.
      Default value is: false.
      User property is: skipProvidedScope. - + skipRuntimeScope @@ -715,7 +723,7 @@ passwords from the settings.xml.
      User property is: serverId Skip Analysis for Runtime Scope Dependencies.
      Default value is: false.
      User property is: skipRuntimeScope. - + skipTestScope @@ -726,7 +734,7 @@ passwords from the settings.xml.
      User property is: serverId Skip Analysis for Test Scope Dependencies.
      Default value is: true.
      User property is: skipTestScope. - + suppressionFile @@ -737,7 +745,7 @@ passwords from the settings.xml.
      User property is: serverId The path to the suppression file.
      User property is: suppressionFile. - + zipExtensions @@ -1013,6 +1021,18 @@ duration in hours.
    87. User Property: databaseUser

    88. +

      enableExperimental:

      + +
      Sets whether Experimental analyzers are enabled. Default is false.
      + +

      externalReport:

      Deprecated. the internal report is no longer supported
      diff --git a/dependency-check-maven/xref-test/index.html b/dependency-check-maven/xref-test/index.html index dee866063..46ddeb355 100644 --- a/dependency-check-maven/xref-test/index.html +++ b/dependency-check-maven/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference + Dependency-Check Maven Plugin 1.4.0 Reference diff --git a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-frame.html b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-frame.html index 6caf5e568..413f12df2 100644 --- a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-frame.html +++ b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference Package org.owasp.dependencycheck.maven + Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven diff --git a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-summary.html b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-summary.html index 5f863e62c..c86605253 100644 --- a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-summary.html +++ b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference Package org.owasp.dependencycheck.maven + Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven diff --git a/dependency-check-maven/xref-test/overview-frame.html b/dependency-check-maven/xref-test/overview-frame.html index 5b9d7ac4c..6b6173eb4 100644 --- a/dependency-check-maven/xref-test/overview-frame.html +++ b/dependency-check-maven/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference + Dependency-Check Maven Plugin 1.4.0 Reference diff --git a/dependency-check-maven/xref-test/overview-summary.html b/dependency-check-maven/xref-test/overview-summary.html index e86d3f429..5a9b7a970 100644 --- a/dependency-check-maven/xref-test/overview-summary.html +++ b/dependency-check-maven/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference + Dependency-Check Maven Plugin 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Maven Plugin 1.3.6 Reference

      +

      Dependency-Check Maven Plugin 1.4.0 Reference

      diff --git a/dependency-check-maven/xref/index.html b/dependency-check-maven/xref/index.html index dee866063..46ddeb355 100644 --- a/dependency-check-maven/xref/index.html +++ b/dependency-check-maven/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference + Dependency-Check Maven Plugin 1.4.0 Reference diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html index dffa5c22a..8b19a40c7 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html @@ -102,1005 +102,1040 @@ 94 @Parameter(defaultValue = "${project.build.directory}", required = true) 95private File outputDirectory; 96/** -97 * Specifies the destination directory for the generated Dependency-Check report. This generally maps to "target/site". -98 */ -99 @Parameter(property = "project.reporting.outputDirectory", required = true) -100private File reportOutputDirectory; -101/** -102 * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which -103 * means since the CVSS scores are 0-10, by default the build will never fail. -104 */ -105 @SuppressWarnings("CanBeFinal") -106 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true) -107privatefloat failBuildOnCVSS = 11; -108/** -109 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default -110 * is true. -111 */ -112 @SuppressWarnings("CanBeFinal") -113 @Parameter(property = "autoUpdate") -114private Boolean autoUpdate; -115/** -116 * Generate aggregate reports in multi-module projects. -117 * -118 * @deprecated use the aggregate goal instead +97 * Specifies the destination directory for the generated Dependency-Check +98 * report. This generally maps to "target/site". +99 */ +100 @Parameter(property = "project.reporting.outputDirectory", required = true) +101private File reportOutputDirectory; +102/** +103 * Specifies if the build should be failed if a CVSS score above a specified +104 * level is identified. The default is 11 which means since the CVSS scores +105 * are 0-10, by default the build will never fail. +106 */ +107 @SuppressWarnings("CanBeFinal") +108 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true) +109privatefloat failBuildOnCVSS = 11; +110/** +111 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +112 * recommended that this be turned to false. Default is true. +113 */ +114 @SuppressWarnings("CanBeFinal") +115 @Parameter(property = "autoUpdate") +116private Boolean autoUpdate; +117/** +118 * Sets whether Experimental analyzers are enabled. Default is false.119 */ -120 @Parameter(property = "aggregate") -121 @Deprecated -122private Boolean aggregate; +120 @SuppressWarnings("CanBeFinal") +121 @Parameter(property = "enableExperimental") +122private Boolean enableExperimental; 123/** -124 * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the -125 * Site plug-in unless the externalReport is set to true. Default is HTML. -126 */ -127 @SuppressWarnings("CanBeFinal") -128 @Parameter(property = "format", defaultValue = "HTML", required = true) -129private String format = "HTML"; -130/** -131 * The Maven settings. -132 */ -133 @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false) -134private org.apache.maven.settings.Settings mavenSettings; -135 -136/** -137 * The maven settings proxy id. -138 */ -139 @SuppressWarnings("CanBeFinal") -140 @Parameter(property = "mavenSettingsProxyId", required = false) -141private String mavenSettingsProxyId; -142 -143/** -144 * The Connection Timeout. -145 */ -146 @Parameter(property = "connectionTimeout", defaultValue = "", required = false) -147private String connectionTimeout; -148/** -149 * The path to the suppression file. -150 */ -151 @Parameter(property = "suppressionFile", defaultValue = "", required = false) -152private String suppressionFile; -153/** -154 * Flag indicating whether or not to show a summary in the output. -155 */ -156 @Parameter(property = "showSummary", defaultValue = "true", required = false) -157privateboolean showSummary = true; -158 -159/** -160 * Whether or not the Jar Analyzer is enabled. -161 */ -162 @Parameter(property = "jarAnalyzerEnabled", required = false) -163private Boolean jarAnalyzerEnabled; -164 -165/** -166 * Whether or not the Archive Analyzer is enabled. -167 */ -168 @Parameter(property = "archiveAnalyzerEnabled", required = false) -169private Boolean archiveAnalyzerEnabled; -170 -171/** -172 * Sets whether the Python Distribution Analyzer will be used. -173 */ -174 @Parameter(property = "pyDistributionAnalyzerEnabled", required = false) -175private Boolean pyDistributionAnalyzerEnabled; -176/** -177 * Sets whether the Python Package Analyzer will be used. -178 */ -179 @Parameter(property = "pyPackageAnalyzerEnabled", required = false) -180private Boolean pyPackageAnalyzerEnabled; -181/** -182 * Sets whether the Ruby Gemspec Analyzer will be used. -183 */ -184 @Parameter(property = "rubygemsAnalyzerEnabled", required = false) -185private Boolean rubygemsAnalyzerEnabled; -186/** -187 * Sets whether or not the openssl Analyzer should be used. -188 */ -189 @Parameter(property = "opensslAnalyzerEnabled", required = false) -190private Boolean opensslAnalyzerEnabled; -191/** -192 * Sets whether or not the CMake Analyzer should be used. -193 */ -194 @Parameter(property = "cmakeAnalyzerEnabled", required = false) -195private Boolean cmakeAnalyzerEnabled; -196/** -197 * Sets whether or not the autoconf Analyzer should be used. -198 */ -199 @Parameter(property = "autoconfAnalyzerEnabled", required = false) -200private Boolean autoconfAnalyzerEnabled; -201/** -202 * Sets whether or not the PHP Composer Lock File Analyzer should be used. -203 */ -204 @Parameter(property = "composerAnalyzerEnabled", required = false) -205private Boolean composerAnalyzerEnabled; -206/** -207 * Sets whether or not the Node.js Analyzer should be used. -208 */ -209 @Parameter(property = "nodeAnalyzerEnabled", required = false) -210private Boolean nodeAnalyzerEnabled; -211 -212/** -213 * Whether or not the .NET Assembly Analyzer is enabled. -214 */ -215 @Parameter(property = "assemblyAnalyzerEnabled", required = false) -216private Boolean assemblyAnalyzerEnabled; -217 -218/** -219 * Whether or not the .NET Nuspec Analyzer is enabled. -220 */ -221 @Parameter(property = "nuspecAnalyzerEnabled", required = false) -222private Boolean nuspecAnalyzerEnabled; -223 -224/** -225 * Whether or not the Central Analyzer is enabled. -226 */ -227 @Parameter(property = "centralAnalyzerEnabled", required = false) -228private Boolean centralAnalyzerEnabled; -229 -230/** -231 * Whether or not the Nexus Analyzer is enabled. -232 */ -233 @Parameter(property = "nexusAnalyzerEnabled", required = false) -234private Boolean nexusAnalyzerEnabled; -235 -236/** -237 * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local). -238 */ -239 @Parameter(property = "nexusUrl", required = false) -240private String nexusUrl; -241/** -242 * Whether or not the configured proxy is used to connect to Nexus. -243 */ -244 @Parameter(property = "nexusUsesProxy", required = false) -245private Boolean nexusUsesProxy; -246/** -247 * The database connection string. +124 * Generate aggregate reports in multi-module projects. +125 * +126 * @deprecated use the aggregate goal instead +127 */ +128 @Parameter(property = "aggregate") +129 @Deprecated +130private Boolean aggregate; +131/** +132 * The report format to be generated (HTML, XML, VULN, ALL). This +133 * configuration option has no affect if using this within the Site plug-in +134 * unless the externalReport is set to true. Default is HTML. +135 */ +136 @SuppressWarnings("CanBeFinal") +137 @Parameter(property = "format", defaultValue = "HTML", required = true) +138private String format = "HTML"; +139/** +140 * The Maven settings. +141 */ +142 @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false) +143private org.apache.maven.settings.Settings mavenSettings; +144 +145/** +146 * The maven settings proxy id. +147 */ +148 @SuppressWarnings("CanBeFinal") +149 @Parameter(property = "mavenSettingsProxyId", required = false) +150private String mavenSettingsProxyId; +151 +152/** +153 * The Connection Timeout. +154 */ +155 @Parameter(property = "connectionTimeout", defaultValue = "", required = false) +156private String connectionTimeout; +157/** +158 * The path to the suppression file. +159 */ +160 @Parameter(property = "suppressionFile", defaultValue = "", required = false) +161private String suppressionFile; +162/** +163 * Flag indicating whether or not to show a summary in the output. +164 */ +165 @Parameter(property = "showSummary", defaultValue = "true", required = false) +166privateboolean showSummary = true; +167 +168/** +169 * Whether or not the Jar Analyzer is enabled. +170 */ +171 @Parameter(property = "jarAnalyzerEnabled", required = false) +172private Boolean jarAnalyzerEnabled; +173 +174/** +175 * Whether or not the Archive Analyzer is enabled. +176 */ +177 @Parameter(property = "archiveAnalyzerEnabled", required = false) +178private Boolean archiveAnalyzerEnabled; +179 +180/** +181 * Sets whether the Python Distribution Analyzer will be used. +182 */ +183 @Parameter(property = "pyDistributionAnalyzerEnabled", required = false) +184private Boolean pyDistributionAnalyzerEnabled; +185/** +186 * Sets whether the Python Package Analyzer will be used. +187 */ +188 @Parameter(property = "pyPackageAnalyzerEnabled", required = false) +189private Boolean pyPackageAnalyzerEnabled; +190/** +191 * Sets whether the Ruby Gemspec Analyzer will be used. +192 */ +193 @Parameter(property = "rubygemsAnalyzerEnabled", required = false) +194private Boolean rubygemsAnalyzerEnabled; +195/** +196 * Sets whether or not the openssl Analyzer should be used. +197 */ +198 @Parameter(property = "opensslAnalyzerEnabled", required = false) +199private Boolean opensslAnalyzerEnabled; +200/** +201 * Sets whether or not the CMake Analyzer should be used. +202 */ +203 @Parameter(property = "cmakeAnalyzerEnabled", required = false) +204private Boolean cmakeAnalyzerEnabled; +205/** +206 * Sets whether or not the autoconf Analyzer should be used. +207 */ +208 @Parameter(property = "autoconfAnalyzerEnabled", required = false) +209private Boolean autoconfAnalyzerEnabled; +210/** +211 * Sets whether or not the PHP Composer Lock File Analyzer should be used. +212 */ +213 @Parameter(property = "composerAnalyzerEnabled", required = false) +214private Boolean composerAnalyzerEnabled; +215/** +216 * Sets whether or not the Node.js Analyzer should be used. +217 */ +218 @Parameter(property = "nodeAnalyzerEnabled", required = false) +219private Boolean nodeAnalyzerEnabled; +220 +221/** +222 * Whether or not the .NET Assembly Analyzer is enabled. +223 */ +224 @Parameter(property = "assemblyAnalyzerEnabled", required = false) +225private Boolean assemblyAnalyzerEnabled; +226 +227/** +228 * Whether or not the .NET Nuspec Analyzer is enabled. +229 */ +230 @Parameter(property = "nuspecAnalyzerEnabled", required = false) +231private Boolean nuspecAnalyzerEnabled; +232 +233/** +234 * Whether or not the Central Analyzer is enabled. +235 */ +236 @Parameter(property = "centralAnalyzerEnabled", required = false) +237private Boolean centralAnalyzerEnabled; +238 +239/** +240 * Whether or not the Nexus Analyzer is enabled. +241 */ +242 @Parameter(property = "nexusAnalyzerEnabled", required = false) +243private Boolean nexusAnalyzerEnabled; +244 +245/** +246 * The URL of a Nexus server's REST API end point +247 * (http://domain/nexus/service/local).248 */ -249 @Parameter(property = "connectionString", defaultValue = "", required = false) -250private String connectionString; -251 -252/** -253 * Returns the connection string. -254 * -255 * @return the connection string -256 */ -257protected String getConnectionString() { -258return connectionString; -259 } -260/** -261 * The database driver name. An example would be org.h2.Driver. -262 */ -263 @Parameter(property = "databaseDriverName", defaultValue = "", required = false) -264private String databaseDriverName; -265/** -266 * The path to the database driver if it is not on the class path. -267 */ -268 @Parameter(property = "databaseDriverPath", defaultValue = "", required = false) -269private String databaseDriverPath; +249 @Parameter(property = "nexusUrl", required = false) +250private String nexusUrl; +251/** +252 * Whether or not the configured proxy is used to connect to Nexus. +253 */ +254 @Parameter(property = "nexusUsesProxy", required = false) +255private Boolean nexusUsesProxy; +256/** +257 * The database connection string. +258 */ +259 @Parameter(property = "connectionString", defaultValue = "", required = false) +260private String connectionString; +261 +262/** +263 * Returns the connection string. +264 * +265 * @return the connection string +266 */ +267protected String getConnectionString() { +268return connectionString; +269 } 270/** -271 * The server id in the settings.xml; used to retrieve encrypted passwords from the settings.xml. +271 * The database driver name. An example would be org.h2.Driver.272 */ -273 @Parameter(property = "serverId", defaultValue = "", required = false) -274private String serverId; +273 @Parameter(property = "databaseDriverName", defaultValue = "", required = false) +274private String databaseDriverName; 275/** -276 * A reference to the settings.xml settings. +276 * The path to the database driver if it is not on the class path.277 */ -278 @Parameter(defaultValue = "${settings}", readonly = true, required = true) -279private org.apache.maven.settings.Settings settingsXml; +278 @Parameter(property = "databaseDriverPath", defaultValue = "", required = false) +279private String databaseDriverPath; 280/** -281 * The security dispatcher that can decrypt passwords in the settings.xml. -282 */ -283 @Component(role = SecDispatcher.class, hint = "default") -284private SecDispatcher securityDispatcher; -285/** -286 * The database user name. -287 */ -288 @Parameter(property = "databaseUser", defaultValue = "", required = false) -289private String databaseUser; -290/** -291 * The password to use when connecting to the database. -292 */ -293 @Parameter(property = "databasePassword", defaultValue = "", required = false) -294private String databasePassword; -295/** -296 * A comma-separated list of file extensions to add to analysis next to jar, zip, .... -297 */ -298 @Parameter(property = "zipExtensions", required = false) -299private String zipExtensions; -300/** -301 * Skip Dependency Check altogether. -302 */ -303 @SuppressWarnings("CanBeFinal") -304 @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false) -305privateboolean skip = false; +281 * The server id in the settings.xml; used to retrieve encrypted passwords +282 * from the settings.xml. +283 */ +284 @Parameter(property = "serverId", defaultValue = "", required = false) +285private String serverId; +286/** +287 * A reference to the settings.xml settings. +288 */ +289 @Parameter(defaultValue = "${settings}", readonly = true, required = true) +290private org.apache.maven.settings.Settings settingsXml; +291/** +292 * The security dispatcher that can decrypt passwords in the settings.xml. +293 */ +294 @Component(role = SecDispatcher.class, hint = "default") +295private SecDispatcher securityDispatcher; +296/** +297 * The database user name. +298 */ +299 @Parameter(property = "databaseUser", defaultValue = "", required = false) +300private String databaseUser; +301/** +302 * The password to use when connecting to the database. +303 */ +304 @Parameter(property = "databasePassword", defaultValue = "", required = false) +305private String databasePassword; 306/** -307 * Skip Analysis for Test Scope Dependencies. -308 */ -309 @SuppressWarnings("CanBeFinal") -310 @Parameter(property = "skipTestScope", defaultValue = "true", required = false) -311privateboolean skipTestScope = true; +307 * A comma-separated list of file extensions to add to analysis next to jar, +308 * zip, .... +309 */ +310 @Parameter(property = "zipExtensions", required = false) +311private String zipExtensions; 312/** -313 * Skip Analysis for Runtime Scope Dependencies. +313 * Skip Dependency Check altogether.314 */315 @SuppressWarnings("CanBeFinal") -316 @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false) -317privateboolean skipRuntimeScope = false; +316 @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false) +317privateboolean skip = false; 318/** -319 * Skip Analysis for Provided Scope Dependencies. +319 * Skip Analysis for Test Scope Dependencies.320 */321 @SuppressWarnings("CanBeFinal") -322 @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false) -323privateboolean skipProvidedScope = false; +322 @Parameter(property = "skipTestScope", defaultValue = "true", required = false) +323privateboolean skipTestScope = true; 324/** -325 * The data directory, hold DC SQL DB. +325 * Skip Analysis for Runtime Scope Dependencies.326 */ -327 @Parameter(property = "dataDirectory", defaultValue = "", required = false) -328private String dataDirectory; -329/** -330 * Data Mirror URL for CVE 1.2. -331 */ -332 @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false) -333private String cveUrl12Modified; -334/** -335 * Data Mirror URL for CVE 2.0. -336 */ -337 @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false) -338private String cveUrl20Modified; -339/** -340 * Base Data Mirror URL for CVE 1.2. -341 */ -342 @Parameter(property = "cveUrl12Base", defaultValue = "", required = false) -343private String cveUrl12Base; -344/** -345 * Data Mirror URL for CVE 2.0. -346 */ -347 @Parameter(property = "cveUrl20Base", defaultValue = "", required = false) -348private String cveUrl20Base; -349/** -350 * Optionally skip excessive CVE update checks for a designated duration in hours. -351 */ -352 @Parameter(property = "cveValidForHours", defaultValue = "", required = false) -353private Integer cveValidForHours; -354 -355/** -356 * The path to mono for .NET Assembly analysis on non-windows systems. -357 */ -358 @Parameter(property = "pathToMono", defaultValue = "", required = false) -359private String pathToMono; -360 +327 @SuppressWarnings("CanBeFinal") +328 @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false) +329privateboolean skipRuntimeScope = false; +330/** +331 * Skip Analysis for Provided Scope Dependencies. +332 */ +333 @SuppressWarnings("CanBeFinal") +334 @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false) +335privateboolean skipProvidedScope = false; +336/** +337 * The data directory, hold DC SQL DB. +338 */ +339 @Parameter(property = "dataDirectory", defaultValue = "", required = false) +340private String dataDirectory; +341/** +342 * Data Mirror URL for CVE 1.2. +343 */ +344 @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false) +345private String cveUrl12Modified; +346/** +347 * Data Mirror URL for CVE 2.0. +348 */ +349 @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false) +350private String cveUrl20Modified; +351/** +352 * Base Data Mirror URL for CVE 1.2. +353 */ +354 @Parameter(property = "cveUrl12Base", defaultValue = "", required = false) +355private String cveUrl12Base; +356/** +357 * Data Mirror URL for CVE 2.0. +358 */ +359 @Parameter(property = "cveUrl20Base", defaultValue = "", required = false) +360private String cveUrl20Base; 361/** -362 * The Proxy URL. -363 * -364 * @deprecated Please use mavenSettings instead -365 */ -366 @SuppressWarnings("CanBeFinal") -367 @Parameter(property = "proxyUrl", defaultValue = "", required = false) -368 @Deprecated -369private String proxyUrl = null; -370/** -371 * Sets whether or not the external report format should be used. -372 * -373 * @deprecated the internal report is no longer supported -374 */ -375 @SuppressWarnings("CanBeFinal") -376 @Parameter(property = "externalReport") -377 @Deprecated -378private String externalReport = null; -379// </editor-fold> -380//<editor-fold defaultstate="collapsed" desc="Base Maven implementation"> -381 -382/** -383 * Executes dependency-check. -384 * -385 * @throws MojoExecutionException thrown if there is an exception executing the mojo -386 * @throws MojoFailureException thrown if dependency-check failed the build +362 * Optionally skip excessive CVE update checks for a designated duration in +363 * hours. +364 */ +365 @Parameter(property = "cveValidForHours", defaultValue = "", required = false) +366private Integer cveValidForHours; +367 +368/** +369 * The path to mono for .NET Assembly analysis on non-windows systems. +370 */ +371 @Parameter(property = "pathToMono", defaultValue = "", required = false) +372private String pathToMono; +373 +374/** +375 * The Proxy URL. +376 * +377 * @deprecated Please use mavenSettings instead +378 */ +379 @SuppressWarnings("CanBeFinal") +380 @Parameter(property = "proxyUrl", defaultValue = "", required = false) +381 @Deprecated +382private String proxyUrl = null; +383/** +384 * Sets whether or not the external report format should be used. +385 * +386 * @deprecated the internal report is no longer supported387 */ -388 @Override -389publicvoid execute() throws MojoExecutionException, MojoFailureException { -390 generatingSite = false; -391if (skip) { -392 getLog().info("Skipping " + getName(Locale.US)); -393 } else { -394 validateAggregate(); -395 project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory); -396 runCheck(); -397 } -398 } -399 -400/** -401 * Checks if the aggregate configuration parameter has been set to true. If it has a MojoExecutionException is thrown because -402 * the aggregate configuration parameter is no longer supported. -403 * -404 * @throws MojoExecutionException thrown if aggregate is set to true -405 */ -406privatevoid validateAggregate() throws MojoExecutionException { -407if (aggregate != null && aggregate) { -408final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. " -409 + "Please use the aggregate goal instead."; -410thrownew MojoExecutionException(msg); +388 @SuppressWarnings("CanBeFinal") +389 @Parameter(property = "externalReport") +390 @Deprecated +391private String externalReport = null; +392// </editor-fold> +393//<editor-fold defaultstate="collapsed" desc="Base Maven implementation"> +394 +395/** +396 * Executes dependency-check. +397 * +398 * @throws MojoExecutionException thrown if there is an exception executing +399 * the mojo +400 * @throws MojoFailureException thrown if dependency-check failed the build +401 */ +402 @Override +403publicvoid execute() throws MojoExecutionException, MojoFailureException { +404 generatingSite = false; +405if (skip) { +406 getLog().info("Skipping " + getName(Locale.US)); +407 } else { +408 validateAggregate(); +409 project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory); +410 runCheck(); 411 } 412 } 413414/** -415 * Generates the Dependency-Check Site Report. -416 * -417 * @param sink the sink to write the report to -418 * @param locale the locale to use when generating the report -419 * @throws MavenReportException if a maven report exception occurs -420 * @deprecated use {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} instead. -421 */ -422 @Override -423 @Deprecated -424publicfinalvoid generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { -425 generate((Sink) sink, locale); -426 } -427 -428/** -429 * A flag indicating whether or not the maven site is being generated. -430 */ -431privateboolean generatingSite = false; -432 -433/** -434 * Returns true if the Maven site is being generated. -435 * -436 * @return true if the Maven site is being generated -437 */ -438protectedboolean isGeneratingSite() { -439return generatingSite; -440 } -441 -442/** -443 * Generates the Dependency-Check Site Report. -444 * -445 * @param sink the sink to write the report to -446 * @param locale the locale to use when generating the report -447 * @throws MavenReportException if a maven report exception occurs -448 */ -449publicvoid generate(Sink sink, Locale locale) throws MavenReportException { -450 generatingSite = true; -451try { -452 validateAggregate(); -453 } catch (MojoExecutionException ex) { -454thrownew MavenReportException(ex.getMessage()); -455 } -456 project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory()); -457try { -458 runCheck(); -459 } catch (MojoExecutionException ex) { -460thrownew MavenReportException(ex.getMessage(), ex); -461 } catch (MojoFailureException ex) { -462 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build"); -463 } -464 } -465 -466/** -467 * Returns the correct output directory depending on if a site is being executed or not. -468 * -469 * @return the directory to write the report(s) -470 * @throws MojoExecutionException thrown if there is an error loading the file path -471 */ -472protected File getCorrectOutputDirectory() throws MojoExecutionException { -473return getCorrectOutputDirectory(this.project); -474 } -475 -476/** -477 * Returns the correct output directory depending on if a site is being executed or not. -478 * -479 * @param current the Maven project to get the output directory from -480 * @return the directory to write the report(s) -481 */ -482protected File getCorrectOutputDirectory(MavenProject current) { -483final Object obj = current.getContextValue(getOutputDirectoryContextKey()); -484if (obj != null && obj instanceof File) { -485return (File) obj; -486 } -487 File target = new File(current.getBuild().getDirectory()); -488if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) { -489 target = target.getParentFile(); -490 } -491return target; -492 } -493 -494/** -495 * Returns the correct output directory depending on if a site is being executed or not. -496 * -497 * @param current the Maven project to get the output directory from -498 * @return the directory to write the report(s) -499 */ -500protected File getDataFile(MavenProject current) { -501if (getLog().isDebugEnabled()) { -502 getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey())); -503 } -504final Object obj = current.getContextValue(getDataFileContextKey()); -505if (obj != null) { -506if (obj instanceof String) { -507final File f = new File((String) obj); -508return f; -509 } -510 } else { -511if (getLog().isDebugEnabled()) { -512 getLog().debug("Context value not found"); -513 } -514 } -515returnnull; -516 } -517 -518/** -519 * Scans the project's artifacts and adds them to the engine's dependency list. -520 * -521 * @param project the project to scan the dependencies of -522 * @param engine the engine to use to scan the dependencies -523 */ -524protectedvoid scanArtifacts(MavenProject project, Engine engine) { -525for (Artifact a : project.getArtifacts()) { -526if (excludeFromScan(a)) { -527continue; -528 } -529final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile()); -530if (deps != null) { -531if (deps.size() == 1) { -532final Dependency d = deps.get(0); -533if (d != null) { -534final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion()); -535 d.addAsEvidence("pom", ma, Confidence.HIGHEST); -536 d.addProjectReference(project.getName()); -537if (getLog().isDebugEnabled()) { -538 getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(), -539 d.getDisplayFileName())); -540 } -541 } -542 } else { -543if (getLog().isDebugEnabled()) { -544final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", -545 a.getGroupId(), a.getArtifactId(), a.getVersion()); -546 getLog().debug(msg); -547 } -548 } -549 } -550 } -551 } -552 -553/** -554 * Executes the dependency-check scan and generates the necassary report. -555 * -556 * @throws MojoExecutionException thrown if there is an exception running the scan -557 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -558 */ -559publicabstractvoid runCheck() throws MojoExecutionException, MojoFailureException; -560 -561/** -562 * Sets the Reporting output directory. -563 * -564 * @param directory the output directory -565 */ -566 @Override -567publicvoid setReportOutputDirectory(File directory) { -568 reportOutputDirectory = directory; +415 * Checks if the aggregate configuration parameter has been set to true. If +416 * it has a MojoExecutionException is thrown because the aggregate +417 * configuration parameter is no longer supported. +418 * +419 * @throws MojoExecutionException thrown if aggregate is set to true +420 */ +421privatevoid validateAggregate() throws MojoExecutionException { +422if (aggregate != null && aggregate) { +423final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. " +424 + "Please use the aggregate goal instead."; +425thrownew MojoExecutionException(msg); +426 } +427 } +428 +429/** +430 * Generates the Dependency-Check Site Report. +431 * +432 * @param sink the sink to write the report to +433 * @param locale the locale to use when generating the report +434 * @throws MavenReportException if a maven report exception occurs +435 * @deprecated use +436 * {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} +437 * instead. +438 */ +439 @Override +440 @Deprecated +441publicfinalvoid generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { +442 generate((Sink) sink, locale); +443 } +444 +445/** +446 * A flag indicating whether or not the maven site is being generated. +447 */ +448privateboolean generatingSite = false; +449 +450/** +451 * Returns true if the Maven site is being generated. +452 * +453 * @return true if the Maven site is being generated +454 */ +455protectedboolean isGeneratingSite() { +456return generatingSite; +457 } +458 +459/** +460 * Generates the Dependency-Check Site Report. +461 * +462 * @param sink the sink to write the report to +463 * @param locale the locale to use when generating the report +464 * @throws MavenReportException if a maven report exception occurs +465 */ +466publicvoid generate(Sink sink, Locale locale) throws MavenReportException { +467 generatingSite = true; +468try { +469 validateAggregate(); +470 } catch (MojoExecutionException ex) { +471thrownew MavenReportException(ex.getMessage()); +472 } +473 project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory()); +474try { +475 runCheck(); +476 } catch (MojoExecutionException ex) { +477thrownew MavenReportException(ex.getMessage(), ex); +478 } catch (MojoFailureException ex) { +479 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build"); +480 } +481 } +482 +483/** +484 * Returns the correct output directory depending on if a site is being +485 * executed or not. +486 * +487 * @return the directory to write the report(s) +488 * @throws MojoExecutionException thrown if there is an error loading the +489 * file path +490 */ +491protected File getCorrectOutputDirectory() throws MojoExecutionException { +492return getCorrectOutputDirectory(this.project); +493 } +494 +495/** +496 * Returns the correct output directory depending on if a site is being +497 * executed or not. +498 * +499 * @param current the Maven project to get the output directory from +500 * @return the directory to write the report(s) +501 */ +502protected File getCorrectOutputDirectory(MavenProject current) { +503final Object obj = current.getContextValue(getOutputDirectoryContextKey()); +504if (obj != null && obj instanceof File) { +505return (File) obj; +506 } +507 File target = new File(current.getBuild().getDirectory()); +508if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) { +509 target = target.getParentFile(); +510 } +511return target; +512 } +513 +514/** +515 * Returns the correct output directory depending on if a site is being +516 * executed or not. +517 * +518 * @param current the Maven project to get the output directory from +519 * @return the directory to write the report(s) +520 */ +521protected File getDataFile(MavenProject current) { +522if (getLog().isDebugEnabled()) { +523 getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey())); +524 } +525final Object obj = current.getContextValue(getDataFileContextKey()); +526if (obj != null) { +527if (obj instanceof String) { +528final File f = new File((String) obj); +529return f; +530 } +531 } elseif (getLog().isDebugEnabled()) { +532 getLog().debug("Context value not found"); +533 } +534returnnull; +535 } +536 +537/** +538 * Scans the project's artifacts and adds them to the engine's dependency +539 * list. +540 * +541 * @param project the project to scan the dependencies of +542 * @param engine the engine to use to scan the dependencies +543 */ +544protectedvoid scanArtifacts(MavenProject project, Engine engine) { +545for (Artifact a : project.getArtifacts()) { +546if (excludeFromScan(a)) { +547continue; +548 } +549final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile()); +550if (deps != null) { +551if (deps.size() == 1) { +552final Dependency d = deps.get(0); +553if (d != null) { +554final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion()); +555 d.addAsEvidence("pom", ma, Confidence.HIGHEST); +556 d.addProjectReference(project.getName()); +557if (getLog().isDebugEnabled()) { +558 getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(), +559 d.getDisplayFileName())); +560 } +561 } +562 } elseif (getLog().isDebugEnabled()) { +563final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", +564 a.getGroupId(), a.getArtifactId(), a.getVersion()); +565 getLog().debug(msg); +566 } +567 } +568 } 569 } 570571/** -572 * Returns the report output directory. +572 * Executes the dependency-check scan and generates the necassary report.573 * -574 * @return the report output directory -575 */ -576 @Override -577public File getReportOutputDirectory() { -578return reportOutputDirectory; -579 } +574 * @throws MojoExecutionException thrown if there is an exception running +575 * the scan +576 * @throws MojoFailureException thrown if dependency-check is configured to +577 * fail the build +578 */ +579publicabstractvoid runCheck() throws MojoExecutionException, MojoFailureException; 580581/** -582 * Returns the output directory. +582 * Sets the Reporting output directory.583 * -584 * @return the output directory +584 * @param directory the output directory585 */ -586public File getOutputDirectory() { -587return outputDirectory; -588 } -589 -590/** -591 * Returns whether this is an external report. This method always returns true. -592 * -593 * @return <code>true</code> -594 */ -595 @Override -596publicfinalboolean isExternalReport() { -597returntrue; -598 } -599 -600/** -601 * Returns the output name. -602 * -603 * @return the output name -604 */ -605 @Override -606public String getOutputName() { -607if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) { -608return"dependency-check-report"; -609 } elseif ("XML".equalsIgnoreCase(this.format)) { -610return"dependency-check-report.xml#"; -611 } elseif ("VULN".equalsIgnoreCase(this.format)) { -612return"dependency-check-vulnerability"; -613 } else { -614 getLog().warn("Unknown report format used during site generation."); -615return"dependency-check-report"; -616 } -617 } -618 -619/** -620 * Returns the category name. -621 * -622 * @return the category name -623 */ -624 @Override -625public String getCategoryName() { -626return MavenReport.CATEGORY_PROJECT_REPORTS; -627 } -628//</editor-fold> -629 -630/** -631 * Initializes a new <code>Engine</code> that can be used for scanning. -632 * -633 * @return a newly instantiated <code>Engine</code> -634 * @throws DatabaseException thrown if there is a database exception -635 */ -636protectedEngine initializeEngine() throws DatabaseException { -637 populateSettings(); -638returnnewEngine(this.project, -639this.reactorProjects); -640 } -641 -642/** -643 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -644 * required to change the proxy url, port, and connection timeout. -645 */ -646protectedvoid populateSettings() { -647 Settings.initialize(); -648 InputStream mojoProperties = null; -649try { -650 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); -651 Settings.mergeProperties(mojoProperties); -652 } catch (IOException ex) { -653 getLog().warn("Unable to load the dependency-check ant task.properties file."); -654if (getLog().isDebugEnabled()) { -655 getLog().debug("", ex); -656 } -657 } finally { -658if (mojoProperties != null) { -659try { -660 mojoProperties.close(); -661 } catch (IOException ex) { -662if (getLog().isDebugEnabled()) { -663 getLog().debug("", ex); -664 } -665 } -666 } -667 } -668 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); -669 -670if (externalReport != null) { -671 getLog().warn("The 'externalReport' option was set; this configuration option has been removed. " -672 + "Please update the dependency-check-maven plugin's configuration"); -673 } -674 -675if (proxyUrl != null && !proxyUrl.isEmpty()) { -676 getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead"); -677 } -678final Proxy proxy = getMavenProxy(); -679if (proxy != null) { -680 Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); -681 Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); -682final String userName = proxy.getUsername(); -683final String password = proxy.getPassword(); -684 Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName); -685 Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password); -686 Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts()); -687 } -688 -689 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -690 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +586 @Override +587publicvoid setReportOutputDirectory(File directory) { +588 reportOutputDirectory = directory; +589 } +590 +591/** +592 * Returns the report output directory. +593 * +594 * @return the report output directory +595 */ +596 @Override +597public File getReportOutputDirectory() { +598return reportOutputDirectory; +599 } +600 +601/** +602 * Returns the output directory. +603 * +604 * @return the output directory +605 */ +606public File getOutputDirectory() { +607return outputDirectory; +608 } +609 +610/** +611 * Returns whether this is an external report. This method always returns +612 * true. +613 * +614 * @return <code>true</code> +615 */ +616 @Override +617publicfinalboolean isExternalReport() { +618returntrue; +619 } +620 +621/** +622 * Returns the output name. +623 * +624 * @return the output name +625 */ +626 @Override +627public String getOutputName() { +628if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) { +629return"dependency-check-report"; +630 } elseif ("XML".equalsIgnoreCase(this.format)) { +631return"dependency-check-report.xml#"; +632 } elseif ("VULN".equalsIgnoreCase(this.format)) { +633return"dependency-check-vulnerability"; +634 } else { +635 getLog().warn("Unknown report format used during site generation."); +636return"dependency-check-report"; +637 } +638 } +639 +640/** +641 * Returns the category name. +642 * +643 * @return the category name +644 */ +645 @Override +646public String getCategoryName() { +647return MavenReport.CATEGORY_PROJECT_REPORTS; +648 } +649//</editor-fold> +650 +651/** +652 * Initializes a new <code>Engine</code> that can be used for scanning. +653 * +654 * @return a newly instantiated <code>Engine</code> +655 * @throws DatabaseException thrown if there is a database exception +656 */ +657protectedEngine initializeEngine() throws DatabaseException { +658 populateSettings(); +659returnnewEngine(this.project, +660this.reactorProjects); +661 } +662 +663/** +664 * Takes the properties supplied and updates the dependency-check settings. +665 * Additionally, this sets the system properties required to change the +666 * proxy url, port, and connection timeout. +667 */ +668protectedvoid populateSettings() { +669 Settings.initialize(); +670 InputStream mojoProperties = null; +671try { +672 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); +673 Settings.mergeProperties(mojoProperties); +674 } catch (IOException ex) { +675 getLog().warn("Unable to load the dependency-check ant task.properties file."); +676if (getLog().isDebugEnabled()) { +677 getLog().debug("", ex); +678 } +679 } finally { +680if (mojoProperties != null) { +681try { +682 mojoProperties.close(); +683 } catch (IOException ex) { +684if (getLog().isDebugEnabled()) { +685 getLog().debug("", ex); +686 } +687 } +688 } +689 } +690 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); 691 -692//File Type Analyzer Settings -693 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); -694 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); -695 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -696 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -697 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -698 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -699 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); -700 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); -701 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -702 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -703 -704 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); -705 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); -706 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); -707 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); -708 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); -709 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); -710 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); -711 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +692 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); +693 +694if (externalReport != null) { +695 getLog().warn("The 'externalReport' option was set; this configuration option has been removed. " +696 + "Please update the dependency-check-maven plugin's configuration"); +697 } +698 +699if (proxyUrl != null && !proxyUrl.isEmpty()) { +700 getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead"); +701 } +702final Proxy proxy = getMavenProxy(); +703if (proxy != null) { +704 Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); +705 Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); +706final String userName = proxy.getUsername(); +707final String password = proxy.getPassword(); +708 Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName); +709 Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password); +710 Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts()); +711 } 712 -713//Database configuration -714 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -715 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -716 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -717 -718if (databaseUser == null && databasePassword == null && serverId != null) { -719final Server server = settingsXml.getServer(serverId); -720if (server != null) { -721 databaseUser = server.getUsername(); -722try { -723//The following fix was copied from: -724// https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java -725// -726// FIX to resolve -727// org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: -728// java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory) -729// -730if (securityDispatcher instanceof DefaultSecDispatcher) { -731 ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml"); -732 } -733 -734 databasePassword = securityDispatcher.decrypt(server.getPassword()); -735 } catch (SecDispatcherException ex) { -736if (ex.getCause() instanceof FileNotFoundException -737 || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) { -738//maybe its not encrypted? -739final String tmp = server.getPassword(); -740if (tmp.startsWith("{") && tmp.endsWith("}")) { -741 getLog().error(String.format( -742"Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", -743 serverId, ex.getMessage())); -744 } else { -745 databasePassword = tmp; -746 } -747 } else { -748 getLog().error(String.format( -749"Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", -750 serverId, ex.getMessage())); -751 } -752 } -753 } else { -754 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId)); -755 } -756 } +713 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +714 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +715 +716//File Type Analyzer Settings +717 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); +718 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); +719 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +720 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +721 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +722 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +723 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); +724 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); +725 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +726 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +727 +728 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); +729 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); +730 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); +731 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); +732 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); +733 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); +734 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); +735 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +736 +737//Database configuration +738 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +739 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +740 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +741 +742if (databaseUser == null && databasePassword == null && serverId != null) { +743final Server server = settingsXml.getServer(serverId); +744if (server != null) { +745 databaseUser = server.getUsername(); +746try { +747//The following fix was copied from: +748// https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java +749// +750// FIX to resolve +751// org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: +752// java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory) +753// +754if (securityDispatcher instanceof DefaultSecDispatcher) { +755 ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml"); +756 } 757 -758 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -759 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -760 Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -761 -762 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); -763 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); -764 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); -765 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); -766 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -767 -768 } -769 -770/** -771 * Returns the maven proxy. -772 * -773 * @return the maven proxy -774 */ -775private Proxy getMavenProxy() { -776if (mavenSettings != null) { -777final List<Proxy> proxies = mavenSettings.getProxies(); -778if (proxies != null && !proxies.isEmpty()) { -779if (mavenSettingsProxyId != null) { -780for (Proxy proxy : proxies) { -781if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) { -782return proxy; -783 } -784 } -785 } elseif (proxies.size() == 1) { -786return proxies.get(0); -787 } else { -788 getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check " -789 + "configuration set the mavenSettingsProxyId so that the correct proxy will be used."); -790thrownew IllegalStateException("Ambiguous proxy definition"); -791 } -792 } -793 } -794returnnull; -795 } -796 -797/** -798 * Tests is the artifact should be included in the scan (i.e. is the dependency in a scope that is being scanned). -799 * -800 * @param a the Artifact to test -801 * @return <code>true</code> if the artifact is in an excluded scope; otherwise <code>false</code> -802 */ -803protectedboolean excludeFromScan(Artifact a) { -804if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { -805returntrue; -806 } -807if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) { -808returntrue; -809 } -810if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) { -811returntrue; -812 } -813return false; -814 } -815 -816/** -817 * Returns a reference to the current project. This method is used instead of auto-binding the project via component -818 * annotation in concrete implementations of this. If the child has a <code>@Component MavenProject project;</code> defined -819 * then the abstract class (i.e. this class) will not have access to the current project (just the way Maven works with the -820 * binding). -821 * -822 * @return returns a reference to the current project -823 */ -824protected MavenProject getProject() { -825return project; -826 } -827 -828/** -829 * Returns the list of Maven Projects in this build. -830 * -831 * @return the list of Maven Projects in this build -832 */ -833protected List<MavenProject> getReactorProjects() { -834return reactorProjects; -835 } -836 -837/** -838 * Returns the report format. -839 * -840 * @return the report format -841 */ -842protected String getFormat() { -843return format; -844 } -845 -846/** -847 * Generates the reports for a given dependency-check engine. -848 * -849 * @param engine a dependency-check engine -850 * @param p the maven project -851 * @param outputDir the directory path to write the report(s). -852 */ -853protectedvoid writeReports(Engine engine, MavenProject p, File outputDir) { -854 DatabaseProperties prop = null; -855 CveDB cve = null; -856try { -857 cve = new CveDB(); -858 cve.open(); -859 prop = cve.getDatabaseProperties(); -860 } catch (DatabaseException ex) { -861if (getLog().isDebugEnabled()) { -862 getLog().debug("Unable to retrieve DB Properties", ex); -863 } -864 } finally { -865if (cve != null) { -866 cve.close(); -867 } -868 } -869final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); -870try { -871 r.generateReports(outputDir.getAbsolutePath(), format); -872 } catch (IOException ex) { -873 getLog().error( -874"Unexpected exception occurred during analysis; please see the verbose error log for more details."); -875if (getLog().isDebugEnabled()) { -876 getLog().debug("", ex); -877 } -878 } catch (Throwable ex) { -879 getLog().error( -880"Unexpected exception occurred during analysis; please see the verbose error log for more details."); -881if (getLog().isDebugEnabled()) { -882 getLog().debug("", ex); -883 } -884 } -885 } -886 -887//<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary"> -888/** -889 * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the -890 * configuration. -891 * -892 * @param dependencies the list of dependency objects -893 * @throws MojoFailureException thrown if a CVSS score is found that is higher then the threshold set -894 */ -895protectedvoid checkForFailure(List<Dependency> dependencies) throws MojoFailureException { -896if (failBuildOnCVSS <= 10) { -897final StringBuilder ids = new StringBuilder(); -898for (Dependency d : dependencies) { -899boolean addName = true; -900for (Vulnerability v : d.getVulnerabilities()) { -901if (v.getCvssScore() >= failBuildOnCVSS) { -902if (addName) { -903 addName = false; -904 ids.append(NEW_LINE).append(d.getFileName()).append(": "); -905 ids.append(v.getName()); -906 } else { -907 ids.append(", ").append(v.getName()); -908 } -909 } -910 } +758 databasePassword = securityDispatcher.decrypt(server.getPassword()); +759 } catch (SecDispatcherException ex) { +760if (ex.getCause() instanceof FileNotFoundException +761 || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) { +762//maybe its not encrypted? +763final String tmp = server.getPassword(); +764if (tmp.startsWith("{") && tmp.endsWith("}")) { +765 getLog().error(String.format( +766"Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", +767 serverId, ex.getMessage())); +768 } else { +769 databasePassword = tmp; +770 } +771 } else { +772 getLog().error(String.format( +773"Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", +774 serverId, ex.getMessage())); +775 } +776 } +777 } else { +778 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId)); +779 } +780 } +781 +782 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +783 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +784 Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +785 +786 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); +787 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); +788 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); +789 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); +790 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +791 +792 } +793 +794/** +795 * Returns the maven proxy. +796 * +797 * @return the maven proxy +798 */ +799private Proxy getMavenProxy() { +800if (mavenSettings != null) { +801final List<Proxy> proxies = mavenSettings.getProxies(); +802if (proxies != null && !proxies.isEmpty()) { +803if (mavenSettingsProxyId != null) { +804for (Proxy proxy : proxies) { +805if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) { +806return proxy; +807 } +808 } +809 } elseif (proxies.size() == 1) { +810return proxies.get(0); +811 } else { +812 getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check " +813 + "configuration set the mavenSettingsProxyId so that the correct proxy will be used."); +814thrownew IllegalStateException("Ambiguous proxy definition"); +815 } +816 } +817 } +818returnnull; +819 } +820 +821/** +822 * Tests is the artifact should be included in the scan (i.e. is the +823 * dependency in a scope that is being scanned). +824 * +825 * @param a the Artifact to test +826 * @return <code>true</code> if the artifact is in an excluded scope; +827 * otherwise <code>false</code> +828 */ +829protectedboolean excludeFromScan(Artifact a) { +830if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { +831returntrue; +832 } +833if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) { +834returntrue; +835 } +836if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) { +837returntrue; +838 } +839return false; +840 } +841 +842/** +843 * Returns a reference to the current project. This method is used instead +844 * of auto-binding the project via component annotation in concrete +845 * implementations of this. If the child has a +846 * <code>@Component MavenProject project;</code> defined then the abstract +847 * class (i.e. this class) will not have access to the current project (just +848 * the way Maven works with the binding). +849 * +850 * @return returns a reference to the current project +851 */ +852protected MavenProject getProject() { +853return project; +854 } +855 +856/** +857 * Returns the list of Maven Projects in this build. +858 * +859 * @return the list of Maven Projects in this build +860 */ +861protected List<MavenProject> getReactorProjects() { +862return reactorProjects; +863 } +864 +865/** +866 * Returns the report format. +867 * +868 * @return the report format +869 */ +870protected String getFormat() { +871return format; +872 } +873 +874/** +875 * Generates the reports for a given dependency-check engine. +876 * +877 * @param engine a dependency-check engine +878 * @param p the maven project +879 * @param outputDir the directory path to write the report(s). +880 */ +881protectedvoid writeReports(Engine engine, MavenProject p, File outputDir) { +882 DatabaseProperties prop = null; +883 CveDB cve = null; +884try { +885 cve = new CveDB(); +886 cve.open(); +887 prop = cve.getDatabaseProperties(); +888 } catch (DatabaseException ex) { +889if (getLog().isDebugEnabled()) { +890 getLog().debug("Unable to retrieve DB Properties", ex); +891 } +892 } finally { +893if (cve != null) { +894 cve.close(); +895 } +896 } +897final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); +898try { +899 r.generateReports(outputDir.getAbsolutePath(), format); +900 } catch (IOException ex) { +901 getLog().error( +902"Unexpected exception occurred during analysis; please see the verbose error log for more details."); +903if (getLog().isDebugEnabled()) { +904 getLog().debug("", ex); +905 } +906 } catch (Throwable ex) { +907 getLog().error( +908"Unexpected exception occurred during analysis; please see the verbose error log for more details."); +909if (getLog().isDebugEnabled()) { +910 getLog().debug("", ex); 911 } -912if (ids.length() > 0) { -913final String msg = String.format("%n%nDependency-Check Failure:%n" -914 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -915 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -916thrownew MojoFailureException(msg); -917 } -918 } -919 } -920 -921/** -922 * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. -923 * -924 * @param mp the Maven project for which the summary is shown -925 * @param dependencies a list of dependency objects -926 */ -927protectedvoid showSummary(MavenProject mp, List<Dependency> dependencies) { -928if (showSummary) { -929final StringBuilder summary = new StringBuilder(); -930for (Dependency d : dependencies) { -931boolean firstEntry = true; -932final StringBuilder ids = new StringBuilder(); -933for (Vulnerability v : d.getVulnerabilities()) { -934if (firstEntry) { -935 firstEntry = false; -936 } else { -937 ids.append(", "); +912 } +913 } +914 +915//<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary"> +916/** +917 * Checks to see if a vulnerability has been identified with a CVSS score +918 * that is above the threshold set in the configuration. +919 * +920 * @param dependencies the list of dependency objects +921 * @throws MojoFailureException thrown if a CVSS score is found that is +922 * higher then the threshold set +923 */ +924protectedvoid checkForFailure(List<Dependency> dependencies) throws MojoFailureException { +925if (failBuildOnCVSS <= 10) { +926final StringBuilder ids = new StringBuilder(); +927for (Dependency d : dependencies) { +928boolean addName = true; +929for (Vulnerability v : d.getVulnerabilities()) { +930if (v.getCvssScore() >= failBuildOnCVSS) { +931if (addName) { +932 addName = false; +933 ids.append(NEW_LINE).append(d.getFileName()).append(": "); +934 ids.append(v.getName()); +935 } else { +936 ids.append(", ").append(v.getName()); +937 } 938 } -939 ids.append(v.getName()); -940 } -941if (ids.length() > 0) { -942 summary.append(d.getFileName()).append(" ("); -943 firstEntry = true; -944for (Identifier id : d.getIdentifiers()) { -945if (firstEntry) { -946 firstEntry = false; -947 } else { -948 summary.append(", "); -949 } -950 summary.append(id.getValue()); -951 } -952 summary.append(") : ").append(ids).append(NEW_LINE); -953 } -954 } -955if (summary.length() > 0) { -956final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s" -957 + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString()); -958 getLog().warn(msg); -959 } -960 } -961 } -962 -963//</editor-fold> -964//<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file"> -965/** -966 * Returns the key used to store the path to the data file that is saved by <code>writeDataFile()</code>. This key is used in -967 * the <code>MavenProject.(set|get)ContextValue</code>. -968 * -969 * @return the key used to store the path to the data file -970 */ -971protected String getDataFileContextKey() { -972return"dependency-check-path-" + dataFileName; -973 } -974 -975/** -976 * Returns the key used to store the path to the output directory. When generating the report in the -977 * <code>executeAggregateReport()</code> the output directory should be obtained by using this key. -978 * -979 * @return the key used to store the path to the output directory -980 */ -981protected String getOutputDirectoryContextKey() { -982return"dependency-output-dir-" + dataFileName; -983 } -984 -985/** -986 * Writes the scan data to disk. This is used to serialize the scan data between the "check" and "aggregate" phase. -987 * -988 * @param mp the mMven project for which the data file was created -989 * @param writeTo the directory to write the data file -990 * @param dependencies the list of dependencies to serialize -991 */ -992protectedvoid writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) { -993 File file; -994//check to see if this was already written out -995if (mp.getContextValue(this.getDataFileContextKey()) == null) { -996if (writeTo == null) { -997 file = new File(mp.getBuild().getDirectory()); -998 file = new File(file, dataFileName); -999 } else { -1000 file = new File(writeTo, dataFileName); -1001 } -1002final File parent = file.getParentFile(); -1003if (!parent.isDirectory() && parent.mkdirs()) { -1004 getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", -1005 parent.getAbsolutePath())); -1006 } -1007 -1008 ObjectOutputStream out = null; -1009try { -1010if (dependencies != null) { -1011 out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); -1012 out.writeObject(dependencies); -1013 } -1014if (getLog().isDebugEnabled()) { -1015 getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s", -1016 file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey())); -1017 } -1018 mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath()); -1019 } catch (IOException ex) { -1020 getLog().warn("Unable to create data file used for report aggregation; " -1021 + "if report aggregation is being used the results may be incomplete."); -1022if (getLog().isDebugEnabled()) { -1023 getLog().debug(ex.getMessage(), ex); -1024 } -1025 } finally { -1026if (out != null) { -1027try { -1028 out.close(); -1029 } catch (IOException ex) { -1030if (getLog().isDebugEnabled()) { -1031 getLog().debug("ignore", ex); -1032 } -1033 } -1034 } -1035 } -1036 } -1037 } -1038 -1039/** -1040 * Reads the serialized scan data from disk. This is used to serialize the scan data between the "check" and "aggregate" -1041 * phase. -1042 * -1043 * @param project the Maven project to read the data file from -1044 * @return a <code>Engine</code> object populated with dependencies if the serialized data file exists; otherwise -1045 * <code>null</code> is returned -1046 */ -1047protected List<Dependency> readDataFile(MavenProject project) { -1048final Object oPath = project.getContextValue(this.getDataFileContextKey()); -1049if (oPath == null) { -1050returnnull; -1051 } -1052 List<Dependency> ret = null; -1053final String path = (String) oPath; -1054//ObjectInputStream ois = null; -1055 ExpectedOjectInputStream ois = null; -1056try { -1057//ois = new ObjectInputStream(new FileInputStream(path)); -1058 ois = new ExpectedOjectInputStream(new FileInputStream(path), -1059"java.util.ArrayList", -1060"java.util.HashSet", -1061"java.util.TreeSet", -1062"java.lang.AbstractSet", -1063"java.lang.AbstractCollection", -1064"java.lang.Enum", -1065"org.owasp.dependencycheck.dependency.Confidence", -1066"org.owasp.dependencycheck.dependency.Dependency", -1067"org.owasp.dependencycheck.dependency.Evidence", -1068"org.owasp.dependencycheck.dependency.EvidenceCollection", -1069"org.owasp.dependencycheck.dependency.Identifier", -1070"org.owasp.dependencycheck.dependency.Reference", -1071"org.owasp.dependencycheck.dependency.Vulnerability", -1072"org.owasp.dependencycheck.dependency.VulnerabilityComparator", -1073"org.owasp.dependencycheck.dependency.VulnerableSoftware", -1074"org.owasp.dependencycheck.data.cpe.IndexEntry"); -1075 ret = (List<Dependency>) ois.readObject(); -1076 } catch (FileNotFoundException ex) { -1077//TODO fix logging -1078 getLog().error("", ex); -1079 } catch (IOException ex) { -1080 getLog().error("", ex); -1081 } catch (ClassNotFoundException ex) { -1082 getLog().error("", ex); -1083 } finally { -1084if (ois != null) { -1085try { -1086 ois.close(); -1087 } catch (IOException ex) { -1088 getLog().error("", ex); -1089 } -1090 } -1091 } -1092return ret; -1093 } -1094//</editor-fold> -1095 } +939 } +940 } +941if (ids.length() > 0) { +942final String msg = String.format("%n%nDependency-Check Failure:%n" +943 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +944 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +945thrownew MojoFailureException(msg); +946 } +947 } +948 } +949 +950/** +951 * Generates a warning message listing a summary of dependencies and their +952 * associated CPE and CVE entries. +953 * +954 * @param mp the Maven project for which the summary is shown +955 * @param dependencies a list of dependency objects +956 */ +957protectedvoid showSummary(MavenProject mp, List<Dependency> dependencies) { +958if (showSummary) { +959final StringBuilder summary = new StringBuilder(); +960for (Dependency d : dependencies) { +961boolean firstEntry = true; +962final StringBuilder ids = new StringBuilder(); +963for (Vulnerability v : d.getVulnerabilities()) { +964if (firstEntry) { +965 firstEntry = false; +966 } else { +967 ids.append(", "); +968 } +969 ids.append(v.getName()); +970 } +971if (ids.length() > 0) { +972 summary.append(d.getFileName()).append(" ("); +973 firstEntry = true; +974for (Identifier id : d.getIdentifiers()) { +975if (firstEntry) { +976 firstEntry = false; +977 } else { +978 summary.append(", "); +979 } +980 summary.append(id.getValue()); +981 } +982 summary.append(") : ").append(ids).append(NEW_LINE); +983 } +984 } +985if (summary.length() > 0) { +986final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s" +987 + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString()); +988 getLog().warn(msg); +989 } +990 } +991 } +992 +993//</editor-fold> +994//<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file"> +995/** +996 * Returns the key used to store the path to the data file that is saved by +997 * <code>writeDataFile()</code>. This key is used in the +998 * <code>MavenProject.(set|get)ContextValue</code>. +999 * +1000 * @return the key used to store the path to the data file +1001 */ +1002protected String getDataFileContextKey() { +1003return"dependency-check-path-" + dataFileName; +1004 } +1005 +1006/** +1007 * Returns the key used to store the path to the output directory. When +1008 * generating the report in the <code>executeAggregateReport()</code> the +1009 * output directory should be obtained by using this key. +1010 * +1011 * @return the key used to store the path to the output directory +1012 */ +1013protected String getOutputDirectoryContextKey() { +1014return"dependency-output-dir-" + dataFileName; +1015 } +1016 +1017/** +1018 * Writes the scan data to disk. This is used to serialize the scan data +1019 * between the "check" and "aggregate" phase. +1020 * +1021 * @param mp the mMven project for which the data file was created +1022 * @param writeTo the directory to write the data file +1023 * @param dependencies the list of dependencies to serialize +1024 */ +1025protectedvoid writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) { +1026 File file; +1027//check to see if this was already written out +1028if (mp.getContextValue(this.getDataFileContextKey()) == null) { +1029if (writeTo == null) { +1030 file = new File(mp.getBuild().getDirectory()); +1031 file = new File(file, dataFileName); +1032 } else { +1033 file = new File(writeTo, dataFileName); +1034 } +1035final File parent = file.getParentFile(); +1036if (!parent.isDirectory() && !parent.mkdirs()) { +1037 getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", +1038 parent.getAbsolutePath())); +1039 } +1040 +1041 ObjectOutputStream out = null; +1042try { +1043if (dependencies != null) { +1044 out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); +1045 out.writeObject(dependencies); +1046 } +1047if (getLog().isDebugEnabled()) { +1048 getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s", +1049 file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey())); +1050 } +1051 mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath()); +1052 } catch (IOException ex) { +1053 getLog().warn("Unable to create data file used for report aggregation; " +1054 + "if report aggregation is being used the results may be incomplete."); +1055if (getLog().isDebugEnabled()) { +1056 getLog().debug(ex.getMessage(), ex); +1057 } +1058 } finally { +1059if (out != null) { +1060try { +1061 out.close(); +1062 } catch (IOException ex) { +1063if (getLog().isDebugEnabled()) { +1064 getLog().debug("ignore", ex); +1065 } +1066 } +1067 } +1068 } +1069 } +1070 } +1071 +1072/** +1073 * Reads the serialized scan data from disk. This is used to serialize the +1074 * scan data between the "check" and "aggregate" phase. +1075 * +1076 * @param project the Maven project to read the data file from +1077 * @return a <code>Engine</code> object populated with dependencies if the +1078 * serialized data file exists; otherwise <code>null</code> is returned +1079 */ +1080protected List<Dependency> readDataFile(MavenProject project) { +1081final Object oPath = project.getContextValue(this.getDataFileContextKey()); +1082if (oPath == null) { +1083returnnull; +1084 } +1085 List<Dependency> ret = null; +1086final String path = (String) oPath; +1087//ObjectInputStream ois = null; +1088 ExpectedOjectInputStream ois = null; +1089try { +1090//ois = new ObjectInputStream(new FileInputStream(path)); +1091 ois = new ExpectedOjectInputStream(new FileInputStream(path), +1092"java.util.ArrayList", +1093"java.util.HashSet", +1094"java.util.TreeSet", +1095"java.lang.AbstractSet", +1096"java.lang.AbstractCollection", +1097"java.lang.Enum", +1098"org.owasp.dependencycheck.dependency.Confidence", +1099"org.owasp.dependencycheck.dependency.Dependency", +1100"org.owasp.dependencycheck.dependency.Evidence", +1101"org.owasp.dependencycheck.dependency.EvidenceCollection", +1102"org.owasp.dependencycheck.dependency.Identifier", +1103"org.owasp.dependencycheck.dependency.Reference", +1104"org.owasp.dependencycheck.dependency.Vulnerability", +1105"org.owasp.dependencycheck.dependency.VulnerabilityComparator", +1106"org.owasp.dependencycheck.dependency.VulnerableSoftware", +1107"org.owasp.dependencycheck.data.cpe.IndexEntry"); +1108 @SuppressWarnings("unchecked") +1109final List<Dependency> depList = (List<Dependency>) ois.readObject(); +1110 ret = depList; +1111 } catch (FileNotFoundException ex) { +1112//TODO fix logging +1113 getLog().error("", ex); +1114 } catch (IOException ex) { +1115 getLog().error("", ex); +1116 } catch (ClassNotFoundException ex) { +1117 getLog().error("", ex); +1118 } finally { +1119if (ois != null) { +1120try { +1121 ois.close(); +1122 } catch (IOException ex) { +1123 getLog().error("", ex); +1124 } +1125 } +1126 } +1127return ret; +1128 } +1129//</editor-fold> +1130 }
      diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-frame.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-frame.html index c3a524c02..eaec0b773 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-frame.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference Package org.owasp.dependencycheck.maven + Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-summary.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-summary.html index f01dd43e5..5f9b4788e 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-summary.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference Package org.owasp.dependencycheck.maven + Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html index 7d6317c1b..9964aef60 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference Package org.owasp.dependencycheck.maven.slf4j + Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven.slf4j diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html index 7f17de225..797175efb 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference Package org.owasp.dependencycheck.maven.slf4j + Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven.slf4j diff --git a/dependency-check-maven/xref/org/slf4j/impl/StaticLoggerBinder.html b/dependency-check-maven/xref/org/slf4j/impl/StaticLoggerBinder.html index 70450ebe0..92e70c7ab 100644 --- a/dependency-check-maven/xref/org/slf4j/impl/StaticLoggerBinder.html +++ b/dependency-check-maven/xref/org/slf4j/impl/StaticLoggerBinder.html @@ -31,92 +31,94 @@ 23import org.slf4j.spi.LoggerFactoryBinder; 2425/** -26 * The binding of org.slf4j.LoggerFactory class with an actual instance of org.slf4j.ILoggerFactory is performed using information -27 * returned by this class. -28 * -29 * @author colezlaw -30 */ -31//CSOFF: FinalClass -32publicclassStaticLoggerBinderimplements LoggerFactoryBinder { -33//CSON: FinalClass -34 -35/** -36 * The unique instance of this class -37 */ -38privatestaticfinalStaticLoggerBinder SINGLETON = newStaticLoggerBinder(); -39 -40/** -41 * Return the singleton of this class. -42 * -43 * @return the StaticLoggerBinder singleton -44 */ -45publicstaticfinalStaticLoggerBinder getSingleton() { -46return SINGLETON; -47 } -48 -49/** -50 * Maven mojos have their own logger, so we'll use one of those -51 */ -52private Log log = null; -53 -54/** -55 * Set the Task which will this is to log through. -56 * -57 * @param log the task through which to log -58 */ -59publicvoid setLog(Log log) { -60this.log = log; -61 loggerFactory = newMavenLoggerFactory(log); -62 } -63 -64/** -65 * Declare the version of the SLF4J API this implementation is compiled against. The value of this filed is usually modified -66 * with each release. -67 */ -68// to avoid constant folding by the compiler, this field must *not* be final -69//CSOFF: StaticVariableName -70//CSOFF: VisibilityModifier -71publicstatic String REQUESTED_API_VERSION = "1.7.12"; // final -72//CSON: VisibilityModifier -73//CSON: StaticVariableName -74 -75/** -76 * The logger factory class string. -77 */ -78privatestaticfinal String LOGGER_FACTORY_CLASS = MavenLoggerFactory.class.getName(); -79 -80/** -81 * The ILoggerFactory instance returned by the {@link #getLoggerFactory} method should always be the same object -82 */ -83private ILoggerFactory loggerFactory; -84 -85/** -86 * Constructs the static logger factory. -87 */ -88privateStaticLoggerBinder() { -89 loggerFactory = newMavenLoggerFactory(log); -90 } -91 -92/** -93 * Returns the logger factory. -94 * -95 * @return the logger factory -96 */ -97 @Override -98public ILoggerFactory getLoggerFactory() { -99return loggerFactory; -100 } -101 -102/** -103 * Returns the logger factory class string. -104 * -105 * @return the logger factory class string -106 */ -107 @Override -108public String getLoggerFactoryClassStr() { -109return LOGGER_FACTORY_CLASS; -110 } -111 } +26 * The binding of org.slf4j.LoggerFactory class with an actual instance of +27 * org.slf4j.ILoggerFactory is performed using information returned by this +28 * class. +29 * +30 * @author colezlaw +31 */ +32//CSOFF: FinalClass +33publicclassStaticLoggerBinderimplements LoggerFactoryBinder { +34//CSON: FinalClass +35 +36/** +37 * The unique instance of this class +38 */ +39privatestaticfinalStaticLoggerBinder SINGLETON = newStaticLoggerBinder(); +40 +41/** +42 * Return the singleton of this class. +43 * +44 * @return the StaticLoggerBinder singleton +45 */ +46publicstaticfinalStaticLoggerBinder getSingleton() { +47return SINGLETON; +48 } +49 +50/** +51 * Maven mojos have their own logger, so we'll use one of those. +52 */ +53private Log log = null; +54 +55/** +56 * Set the Task which will this is to log through. +57 * +58 * @param log the task through which to log +59 */ +60publicvoid setLog(Log log) { +61this.log = log; +62 loggerFactory = newMavenLoggerFactory(log); +63 } +64 +65/** +66 * Declare the version of the SLF4J API this implementation is compiled +67 * against. The value of this filed is usually modified with each release. +68 */ +69// to avoid constant folding by the compiler, this field must *not* be final +70//CSOFF: StaticVariableName +71//CSOFF: VisibilityModifier +72publicstatic String REQUESTED_API_VERSION = "1.7.12"; // final +73//CSON: VisibilityModifier +74//CSON: StaticVariableName +75 +76/** +77 * The logger factory class string. +78 */ +79privatestaticfinal String LOGGER_FACTORY_CLASS = MavenLoggerFactory.class.getName(); +80 +81/** +82 * The ILoggerFactory instance returned by the {@link #getLoggerFactory} +83 * method should always be the same object +84 */ +85private ILoggerFactory loggerFactory; +86 +87/** +88 * Constructs the static logger factory. +89 */ +90privateStaticLoggerBinder() { +91 loggerFactory = newMavenLoggerFactory(log); +92 } +93 +94/** +95 * Returns the logger factory. +96 * +97 * @return the logger factory +98 */ +99 @Override +100public ILoggerFactory getLoggerFactory() { +101return loggerFactory; +102 } +103 +104/** +105 * Returns the logger factory class string. +106 * +107 * @return the logger factory class string +108 */ +109 @Override +110public String getLoggerFactoryClassStr() { +111return LOGGER_FACTORY_CLASS; +112 } +113 }
      diff --git a/dependency-check-maven/xref/org/slf4j/impl/package-frame.html b/dependency-check-maven/xref/org/slf4j/impl/package-frame.html index 44fe05721..fdd586e97 100644 --- a/dependency-check-maven/xref/org/slf4j/impl/package-frame.html +++ b/dependency-check-maven/xref/org/slf4j/impl/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference Package org.slf4j.impl + Dependency-Check Maven Plugin 1.4.0 Reference Package org.slf4j.impl diff --git a/dependency-check-maven/xref/org/slf4j/impl/package-summary.html b/dependency-check-maven/xref/org/slf4j/impl/package-summary.html index 6f519baf4..9cc4a5306 100644 --- a/dependency-check-maven/xref/org/slf4j/impl/package-summary.html +++ b/dependency-check-maven/xref/org/slf4j/impl/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference Package org.slf4j.impl + Dependency-Check Maven Plugin 1.4.0 Reference Package org.slf4j.impl diff --git a/dependency-check-maven/xref/overview-frame.html b/dependency-check-maven/xref/overview-frame.html index ca78cdf02..a8f16b895 100644 --- a/dependency-check-maven/xref/overview-frame.html +++ b/dependency-check-maven/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference + Dependency-Check Maven Plugin 1.4.0 Reference diff --git a/dependency-check-maven/xref/overview-summary.html b/dependency-check-maven/xref/overview-summary.html index f5eb8c197..57365031d 100644 --- a/dependency-check-maven/xref/overview-summary.html +++ b/dependency-check-maven/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.3.6 Reference + Dependency-Check Maven Plugin 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Maven Plugin 1.3.6 Reference

      +

      Dependency-Check Maven Plugin 1.4.0 Reference

      diff --git a/dependency-check-utils/apidocs/allclasses-frame.html b/dependency-check-utils/apidocs/allclasses-frame.html index 3f6b0db5d..f4d4aa5e2 100644 --- a/dependency-check-utils/apidocs/allclasses-frame.html +++ b/dependency-check-utils/apidocs/allclasses-frame.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Utils 1.3.6 API) - +All Classes (Dependency-Check Utils 1.4.0 API) + diff --git a/dependency-check-utils/apidocs/allclasses-noframe.html b/dependency-check-utils/apidocs/allclasses-noframe.html index 1e5583b1f..a5b1f115b 100644 --- a/dependency-check-utils/apidocs/allclasses-noframe.html +++ b/dependency-check-utils/apidocs/allclasses-noframe.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Utils 1.3.6 API) - +All Classes (Dependency-Check Utils 1.4.0 API) + diff --git a/dependency-check-utils/apidocs/constant-values.html b/dependency-check-utils/apidocs/constant-values.html index 81e97cf24..b509cfd06 100644 --- a/dependency-check-utils/apidocs/constant-values.html +++ b/dependency-check-utils/apidocs/constant-values.html @@ -2,10 +2,10 @@ - + -Constant Field Values (Dependency-Check Utils 1.3.6 API) - +Constant Field Values (Dependency-Check Utils 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/package-summary.html index 4e32560a6..45effd9e4 100644 --- a/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.utils (Dependency-Check Utils 1.3.6 API) - +org.owasp.dependencycheck.utils (Dependency-Check Utils 1.4.0 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ - + diff --git a/dependency-check-utils/cobertura/frame-summary.html b/dependency-check-utils/cobertura/frame-summary.html index 64aa897ea..5c10ae294 100644 --- a/dependency-check-utils/cobertura/frame-summary.html +++ b/dependency-check-utils/cobertura/frame-summary.html @@ -25,6 +25,6 @@ var packageTable = new SortableTable(document.getElementById("packageResults"), ["String", "Number", "Percentage", "Percentage", "FormattedNumber"]); packageTable.sort(0); - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Checksum.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Checksum.html index aba197386..962af8c4f 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Checksum.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Checksum.html @@ -99,7 +99,7 @@ - + @@ -134,44 +134,44 @@ - - + + - - - - - + + + + + - + - - + + - - - - + + + + - + - + - + - + @@ -194,8 +194,8 @@ - - + + @@ -218,8 +218,8 @@ - - + + @@ -256,22 +256,22 @@ - + - - - + + + - +
            * The logger.
       41  
            */
       42  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Checksum.class);
       42  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Checksum.class);
       43  
       
       44  
            */
       60  
           public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
       61  5
               MessageDigest digest = MessageDigest.getInstance(algorithm);
       62  4
               FileInputStream fis = null;
       61  10
               MessageDigest digest = MessageDigest.getInstance(algorithm);
       62  8
               FileInputStream fis = null;
       63  
               try {
       64  4
                   fis = new FileInputStream(file);
       65  3
                   FileChannel ch = fis.getChannel();
       66  3
                   long remainingToRead = file.length();
       67  3
                   long start = 0;
       68  6
                   while (remainingToRead > 0) {
       64  8
                   fis = new FileInputStream(file);
       65  6
                   FileChannel ch = fis.getChannel();
       66  6
                   long remainingToRead = file.length();
       67  6
                   long start = 0;
       68  12
                   while (remainingToRead > 0) {
       69  
                       long amountToRead;
       70  3
                       if (remainingToRead > Integer.MAX_VALUE) {
       70  6
                       if (remainingToRead > Integer.MAX_VALUE) {
       71  0
                           remainingToRead -= Integer.MAX_VALUE;
       72  0
                           amountToRead = Integer.MAX_VALUE;
       73  
                       } else {
       74  3
                           amountToRead = remainingToRead;
       75  3
                           remainingToRead = 0;
       74  6
                           amountToRead = remainingToRead;
       75  6
                           remainingToRead = 0;
       76  
                       }
       77  3
                       MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, start, amountToRead);
       78  3
                       digest.update(byteBuffer);
       79  3
                       start += amountToRead;
       80  3
                   }
       77  6
                       MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, start, amountToRead);
       78  6
                       digest.update(byteBuffer);
       79  6
                       start += amountToRead;
       80  6
                   }
       81  
               } finally {
       82  4
                   if (fis != null) {
       82  8
                   if (fis != null) {
       83  
                       try {
       84  3
                           fis.close();
       84  6
                           fis.close();
       85  0
                       } catch (IOException ex) {
       86  0
                           LOGGER.trace("Error closing file '{}'.", file.getName(), ex);
       87  4
                       }
       87  8
                       }
       88  
                   }
       89  
               }
       90  3
               return digest.digest();
       90  6
               return digest.digest();
       91  
           }
       92  
            */
       101  
           public static String getMD5Checksum(File file) throws IOException, NoSuchAlgorithmException {
       102  1
               byte[] b = getChecksum("MD5", file);
       103  1
               return getHex(b);
       102  2
               byte[] b = getChecksum("MD5", file);
       103  2
               return getHex(b);
       104  
           }
       105  
            */
       114  
           public static String getSHA1Checksum(File file) throws IOException, NoSuchAlgorithmException {
       115  1
               byte[] b = getChecksum("SHA1", file);
       116  1
               return getHex(b);
       115  2
               byte[] b = getChecksum("SHA1", file);
       116  2
               return getHex(b);
       117  
           }
       118  
            */
       134  
           public static String getHex(byte[] raw) {
       135  3
               if (raw == null) {
       135  6
               if (raw == null) {
       136  0
                   return null;
       137  
               }
       138  3
               final StringBuilder hex = new StringBuilder(2 * raw.length);
       139  56
               for (final byte b : raw) {
       140  53
                   hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt(b & 0x0F));
       138  6
               final StringBuilder hex = new StringBuilder(2 * raw.length);
       139  112
               for (final byte b : raw) {
       140  106
                   hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt(b & 0x0F));
       141  
               }
       142  3
               return hex.toString();
       142  6
               return hex.toString();
       143  
           }
       144  
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.DownloadFailedException.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.DownloadFailedException.html index 48e167009..38cd2492c 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.DownloadFailedException.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.DownloadFailedException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Downloader.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Downloader.html index eee6c4d80..1ed19286e 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Downloader.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Downloader.html @@ -109,7 +109,7 @@
            * The logger.
       46  
            */
      -  47  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Downloader.class);
      +  47  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Downloader.class);
       48  
           /**
       49   @@ -358,21 +358,21 @@
            */
       215  
           public static long getLastModified(URL url) throws DownloadFailedException {
      -  216  1
               long timestamp = 0;
      +  216  2
               long timestamp = 0;
       217  
               //TODO add the FTP protocol?
      -  218  1
               if ("file".equalsIgnoreCase(url.getProtocol())) {
      +  218  2
               if ("file".equalsIgnoreCase(url.getProtocol())) {
       219  
                   File lastModifiedFile;
       220  
                   try {
      -  221  1
                       lastModifiedFile = new File(url.toURI());
      +  221  2
                       lastModifiedFile = new File(url.toURI());
       222  0
                   } catch (URISyntaxException ex) {
       223  0
                       final String msg = format("Unable to locate '%s'", url.toString());
       224  0
                       throw new DownloadFailedException(msg);
      -  225  1
                   }
      -  226  1
                   timestamp = lastModifiedFile.lastModified();
      -  227  1
               } else {
      +  225  2
                   }
      +  226  2
                   timestamp = lastModifiedFile.lastModified();
      +  227  2
               } else {
       228  0
                   final String httpMethod = determineHttpMethod();
       229  0
                   HttpURLConnection conn = null;
       230   @@ -423,7 +423,7 @@
                   }
       264  
               }
      -  265  1
               return timestamp;
      +  265  2
               return timestamp;
       266  
           }
       267   @@ -512,6 +512,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExpectedOjectInputStream.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExpectedOjectInputStream.html index 6dc44ecaa..147048543 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExpectedOjectInputStream.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExpectedOjectInputStream.html @@ -93,7 +93,7 @@
            * The list of fully qualified class names that are able to be deserialized.
       38  
            */
      -  39  2
           private List<String> expected = new ArrayList<String>();
      +  39  4
           private List<String> expected = new ArrayList<String>();
       40  
       
       41   @@ -114,9 +114,9 @@
            */
       49  
           public ExpectedOjectInputStream(InputStream inputStream, String... expected) throws IOException {
      -  50  2
               super(inputStream);
      -  51  2
               this.expected.addAll(Arrays.asList(expected));
      -  52  2
           }
      +  50  4
               super(inputStream);
      +  51  4
               this.expected.addAll(Arrays.asList(expected));
      +  52  4
           }
       53  
       
       54   @@ -141,17 +141,17 @@
           @Override
       64  
           protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
      -  65  7
               if (!this.expected.contains(desc.getName())) {
      -  66  1
                   throw new InvalidClassException("Unexpected deserialization ", desc.getName());
      +  65  14
               if (!this.expected.contains(desc.getName())) {
      +  66  2
                   throw new InvalidClassException("Unexpected deserialization ", desc.getName());
       67  
               }
      -  68  6
               return super.resolveClass(desc);
      +  68  12
               return super.resolveClass(desc);
       69  
           }
       70  
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExtractionException.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExtractionException.html index aea48e744..5ae133f3e 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExtractionException.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExtractionException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.FileUtils.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.FileUtils.html index 029b17fc8..032bd35c1 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.FileUtils.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.FileUtils.html @@ -91,7 +91,7 @@
            * The logger.
       37  
            */
      -  38  1
           private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
      +  38  2
           private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
       39  
           /**
       40   @@ -136,8 +136,8 @@
            */
       61  
           public static String getFileExtension(String fileName) {
      -  62  3
               final String fileExt = FilenameUtils.getExtension(fileName);
      -  63  3
               return null == fileExt || fileExt.isEmpty() ? null : fileExt.toLowerCase();
      +  62  6
               final String fileExt = FilenameUtils.getExtension(fileName);
      +  63  6
               return null == fileExt || fileExt.isEmpty() ? null : fileExt.toLowerCase();
       64  
           }
       65   @@ -156,13 +156,13 @@
            */
       72  
           public static boolean delete(File file) {
      -  73  3
               final boolean success = org.apache.commons.io.FileUtils.deleteQuietly(file);
      -  74  3
               if (!success) {
      +  73  6
               final boolean success = org.apache.commons.io.FileUtils.deleteQuietly(file);
      +  74  6
               if (!success) {
       75  0
                   LOGGER.debug("Failed to delete file: {}; attempting to delete on exit.", file.getPath());
       76  0
                   file.deleteOnExit();
       77  
               }
      -  78  3
               return success;
      +  78  6
               return success;
       79  
           }
       80   @@ -222,6 +222,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.InvalidSettingException.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.InvalidSettingException.html index 4ca6c6c0e..1f94a2fab 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.InvalidSettingException.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.InvalidSettingException.html @@ -107,8 +107,8 @@
            */
       46  
           public InvalidSettingException(String msg) {
      -  47  1
               super(msg);
      -  48  1
           }
      +  47  2
               super(msg);
      +  48  2
           }
       49  
       
       50   @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Settings.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Settings.html index b294261ea..e13e176ea 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Settings.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Settings.html @@ -401,1153 +401,1161 @@  192  
               /**
       193   -
                * The properties key for whether the Archive analyzer is enabled.
      +
                * The properties key for whether experimental analyzers are loaded.
       194  
                */
       195   -
               public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled";
      +
               public static final String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled";
       196  
               /**
       197   -
                * The properties key for whether the node.js package analyzer is enabled.
      +
                * The properties key for whether the Archive analyzer is enabled.
       198  
                */
       199   -
               public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled";
      +
               public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled";
       200  
               /**
       201   -
                * The properties key for whether the composer lock file analyzer is enabled.
      +
                * The properties key for whether the node.js package analyzer is enabled.
       202  
                */
       203   -
               public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled";
      +
               public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled";
       204  
               /**
       205   -
                * The properties key for whether the Python Distribution analyzer is enabled.
      +
                * The properties key for whether the composer lock file analyzer is enabled.
       206  
                */
       207   -
               public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled";
      +
               public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled";
       208  
               /**
       209   -
                * The properties key for whether the Python Package analyzer is enabled.
      +
                * The properties key for whether the Python Distribution analyzer is enabled.
       210  
                */
       211   -
               public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled";
      +
               public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled";
       212  
               /**
       213   -
                * The properties key for whether the Ruby Gemspec Analyzer is enabled.
      +
                * The properties key for whether the Python Package analyzer is enabled.
       214  
                */
       215   -
               public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled";
      +
               public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled";
       216  
               /**
       217   -
                * The properties key for whether the Autoconf analyzer is enabled.
      +
                * The properties key for whether the Ruby Gemspec Analyzer is enabled.
       218  
                */
       219   -
               public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled";
      +
               public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled";
       220  
               /**
       221   -
                * The properties key for whether the CMake analyzer is enabled.
      +
                * The properties key for whether the Autoconf analyzer is enabled.
       222  
                */
       223   -
               public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled";
      +
               public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled";
       224  
               /**
       225   -
                * The properties key for whether the Ruby Bundler Audit analyzer is enabled.
      +
                * The properties key for whether the CMake analyzer is enabled.
       226  
                */
       227   -
               public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled";
      +
               public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled";
       228  
               /**
       229   -
                * The properties key for whether the .NET Assembly analyzer is enabled.
      +
                * The properties key for whether the Ruby Bundler Audit analyzer is enabled.
       230  
                */
       231   -
               public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled";
      +
               public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled";
       232  
               /**
       233   -
                * The properties key for whether the .NET Nuspec analyzer is enabled.
      +
                * The properties key for whether the .NET Assembly analyzer is enabled.
       234  
                */
       235   -
               public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled";
      +
               public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled";
       236  
               /**
       237   -
                * The properties key for whether the Nexus analyzer is enabled.
      +
                * The properties key for whether the .NET Nuspec analyzer is enabled.
       238  
                */
       239   -
               public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled";
      +
               public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled";
       240  
               /**
       241   -
                * The properties key for the Nexus search URL.
      +
                * The properties key for whether the Nexus analyzer is enabled.
       242  
                */
       243   -
               public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url";
      +
               public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled";
       244  
               /**
       245   -
                * The properties key for using the proxy to reach Nexus.
      +
                * The properties key for the Nexus search URL.
       246  
                */
       247   -
               public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy";
      +
               public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url";
       248  
               /**
       249   -
                * The properties key for whether the Central analyzer is enabled.
      +
                * The properties key for using the proxy to reach Nexus.
       250  
                */
       251   -
               public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled";
      +
               public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy";
       252  
               /**
       253   -
                * The properties key for whether the OpenSSL analyzer is enabled.
      +
                * The properties key for whether the Central analyzer is enabled.
       254  
                */
       255   -
               public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled";
      +
               public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled";
       256  
               /**
       257   -
                * The properties key for the Central search URL.
      +
                * The properties key for whether the OpenSSL analyzer is enabled.
       258  
                */
       259   -
               public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url";
      +
               public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled";
       260  
               /**
       261   -
                * The path to mono, if available.
      +
                * The properties key for the Central search URL.
       262  
                */
       263   -
               public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path";
      +
               public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url";
       264  
               /**
       265   -
                * The path to bundle-audit, if available.
      +
                * The path to mono, if available.
       266  
                */
       267   -
               public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path";
      +
               public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path";
       268  
               /**
       269   -
                * The additional configured zip file extensions, if available.
      +
                * The path to bundle-audit, if available.
       270  
                */
       271   -
               public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip";
      +
               public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path";
       272  
               /**
       273   -
                * The key to obtain the path to the VFEED data file.
      +
                * The additional configured zip file extensions, if available.
       274  
                */
       275   -
               public static final String VFEED_DATA_FILE = "vfeed.data_file";
      +
               public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip";
       276  
               /**
       277   -
                * The key to obtain the VFEED connection string.
      +
                * The key to obtain the path to the VFEED data file.
       278  
                */
       279   -
               public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string";
      +
               public static final String VFEED_DATA_FILE = "vfeed.data_file";
       280   -
       
      -  281  
               /**
      +  281   +
                * The key to obtain the VFEED connection string.
       282   -
                * The key to obtain the base download URL for the VFeed data file.
      -  283  
                */
      +  283   +
               public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string";
       284   -
               public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url";
      +
       
       285  
               /**
       286   -
                * The key to obtain the download file name for the VFeed data.
      +
                * The key to obtain the base download URL for the VFeed data file.
       287  
                */
       288   -
               public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file";
      +
               public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url";
       289  
               /**
       290   -
                * The key to obtain the VFeed update status.
      +
                * The key to obtain the download file name for the VFeed data.
       291  
                */
       292   -
               public static final String VFEED_UPDATE_STATUS = "vfeed.update_status";
      +
               public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file";
       293   -
       
      -  294  
               /**
      +  294   +
                * The key to obtain the VFeed update status.
       295   -
                * The HTTP request method for query last modified date.
      -  296  
                */
      +  296   +
               public static final String VFEED_UPDATE_STATUS = "vfeed.update_status";
       297   -
               public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp";
      -  298   -
           }
      -  299   -
           //</editor-fold>
      -  300  
       
      +  298   +
               /**
      +  299   +
                * The HTTP request method for query last modified date.
      +  300   +
                */
       301   -
           /**
      +
               public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp";
       302   -
            * The logger.
      +
           }
       303   -
            */
      -  304  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class);
      +
           //</editor-fold>
      +  304   +
       
       305  
           /**
       306   -
            * The properties file location.
      +
            * The logger.
       307  
            */
      -  308   -
           private static final String PROPERTIES_FILE = "dependencycheck.properties";
      +  308  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class);
       309  
           /**
       310   -
            * Thread local settings.
      +
            * The properties file location.
       311  
            */
      -  312  1
           private static ThreadLocal<Settings> localSettings = new ThreadLocal<Settings>();
      +  312   +
           private static final String PROPERTIES_FILE = "dependencycheck.properties";
       313  
           /**
       314   -
            * The properties.
      +
            * Thread local settings.
       315  
            */
      -  316  2
           private Properties props = null;
      +  316  2
           private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>();
       317   -
       
      +
           /**
       318   -
           /**
      +
            * The properties.
       319   -
            * Private constructor for the Settings class. This class loads the properties files.
      -  320   -
            *
      +
            */
      +  320  4
           private Properties props = null;
       321   -
            * @param propertiesFilePath the path to the base properties file to load
      +
       
       322   -
            */
      -  323  2
           private Settings(String propertiesFilePath) {
      -  324  2
               InputStream in = null;
      -  325  2
               props = new Properties();
      -  326   -
               try {
      -  327  2
                   in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath);
      -  328  2
                   props.load(in);
      -  329  0
               } catch (IOException ex) {
      -  330  0
                   LOGGER.error("Unable to load default settings.");
      -  331  0
                   LOGGER.debug("", ex);
      -  332   -
               } finally {
      -  333  2
                   if (in != null) {
      -  334   -
                       try {
      -  335  2
                           in.close();
      -  336  0
                       } catch (IOException ex) {
      -  337  0
                           LOGGER.trace("", ex);
      -  338  2
                       }
      -  339   -
                   }
      -  340   -
               }
      -  341  2
               logProperties("Properties loaded", props);
      -  342  2
           }
      -  343   -
       
      -  344  
           /**
      -  345   -
            * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must
      -  346   -
            * also call Settings.cleanup() to properly release resources.
      -  347   -
            */
      -  348   -
           public static void initialize() {
      -  349  2
               localSettings.set(new Settings(PROPERTIES_FILE));
      -  350  2
           }
      -  351   -
       
      -  352   -
           /**
      -  353   -
            * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must
      -  354   -
            * also call Settings.cleanup() to properly release resources.
      -  355   +  323   +
            * Private constructor for the Settings class. This class loads the properties files.
      +  324  
            *
      -  356   +  325  
            * @param propertiesFilePath the path to the base properties file to load
      +  326   +
            */
      +  327  4
           private Settings(String propertiesFilePath) {
      +  328  4
               InputStream in = null;
      +  329  4
               props = new Properties();
      +  330   +
               try {
      +  331  4
                   in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath);
      +  332  4
                   props.load(in);
      +  333  0
               } catch (IOException ex) {
      +  334  0
                   LOGGER.error("Unable to load default settings.");
      +  335  0
                   LOGGER.debug("", ex);
      +  336   +
               } finally {
      +  337  4
                   if (in != null) {
      +  338   +
                       try {
      +  339  4
                           in.close();
      +  340  0
                       } catch (IOException ex) {
      +  341  0
                           LOGGER.trace("", ex);
      +  342  4
                       }
      +  343   +
                   }
      +  344   +
               }
      +  345  4
               logProperties("Properties loaded", props);
      +  346  4
           }
      +  347   +
       
      +  348   +
           /**
      +  349   +
            * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must
      +  350   +
            * also call Settings.cleanup() to properly release resources.
      +  351   +
            */
      +  352   +
           public static void initialize() {
      +  353  4
               LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE));
      +  354  4
           }
      +  355   +
       
      +  356   +
           /**
       357   -
            */
      +
            * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must
       358   -
           public static void initialize(String propertiesFilePath) {
      -  359  0
               localSettings.set(new Settings(propertiesFilePath));
      -  360  0
           }
      +
            * also call Settings.cleanup() to properly release resources.
      +  359   +
            *
      +  360   +
            * @param propertiesFilePath the path to the base properties file to load
       361   -
       
      +
            */
       362   -
           /**
      -  363   -
            * Cleans up resources to prevent memory leaks.
      -  364   -
            *
      +
           public static void initialize(String propertiesFilePath) {
      +  363  0
               LOCAL_SETTINGS.set(new Settings(propertiesFilePath));
      +  364  0
           }
       365   -
            */
      +
       
       366   -
           public static void cleanup() {
      -  367  0
               cleanup(true);
      -  368  0
           }
      -  369   -
       
      -  370  
           /**
      -  371   +  367  
            * Cleans up resources to prevent memory leaks.
      -  372   +  368  
            *
      +  369   +
            */
      +  370   +
           public static void cleanup() {
      +  371  0
               cleanup(true);
      +  372  0
           }
       373   -
            * @param deleteTemporary flag indicating whether any temporary directories generated should be removed
      +
       
       374   -
            */
      +
           /**
       375   -
           public static void cleanup(boolean deleteTemporary) {
      -  376  2
               if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) {
      -  377  2
                   FileUtils.delete(tempDirectory);
      -  378  2
                   if (tempDirectory.exists()) {
      +
            * Cleans up resources to prevent memory leaks.
      +  376   +
            *
      +  377   +
            * @param deleteTemporary flag indicating whether any temporary directories generated should be removed
      +  378   +
            */
       379   +
           public static void cleanup(boolean deleteTemporary) {
      +  380  4
               if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) {
      +  381  4
                   FileUtils.delete(tempDirectory);
      +  382  4
                   if (tempDirectory.exists()) {
      +  383  
                       try {
      -  380  0
                           Thread.sleep(2000);
      -  381  0
                       } catch (InterruptedException ex) {
      -  382  0
                           LOGGER.trace("ignore", ex);
      -  383  0
                       }
      -  384  0
                       FileUtils.delete(tempDirectory);
      -  385   +  384  0
                           Thread.sleep(2000);
      +  385  0
                       } catch (InterruptedException ex) {
      +  386  0
                           LOGGER.trace("ignore", ex);
      +  387  0
                       }
      +  388  0
                       FileUtils.delete(tempDirectory);
      +  389  
                   }
      -  386   +  390  
               }
      -  387   +  391  
               try {
      -  388  2
                   localSettings.remove();
      -  389  0
               } catch (Throwable ex) {
      -  390  0
                   LOGGER.debug("Error cleaning up Settings", ex);
      -  391  2
               }
      -  392  2
           }
      -  393   -
       
      -  394   -
           /**
      -  395   -
            * Gets the underlying instance of the Settings object.
      -  396   -
            *
      +  392  4
                   LOCAL_SETTINGS.remove();
      +  393  0
               } catch (Throwable ex) {
      +  394  0
                   LOGGER.debug("Error cleaning up Settings", ex);
      +  395  4
               }
      +  396  4
           }
       397   -
            * @return the Settings object
      +
       
       398   -
            */
      +
           /**
       399   -
           public static Settings getInstance() {
      -  400  0
               return localSettings.get();
      +
            * Gets the underlying instance of the Settings object.
      +  400   +
            *
       401   -
           }
      +
            * @return the Settings object
       402   -
       
      +
            */
       403   -
           /**
      -  404   -
            * Sets the instance of the Settings object to use in this thread.
      +
           public static Settings getInstance() {
      +  404  0
               return LOCAL_SETTINGS.get();
       405   -
            *
      -  406   -
            * @param instance the instance of the settings object to use in this thread
      -  407   -
            */
      -  408   -
           public static void setInstance(Settings instance) {
      -  409  0
               localSettings.set(instance);
      -  410  0
           }
      -  411   -
       
      -  412   -
           /**
      -  413   -
            * Logs the properties. This will not log any properties that contain 'password' in the key.
      -  414   -
            *
      -  415   -
            * @param header the header to print with the log message
      -  416   -
            * @param properties the properties to log
      -  417   -
            */
      -  418   -
           private static void logProperties(String header, Properties properties) {
      -  419  3
               if (LOGGER.isDebugEnabled()) {
      -  420  0
                   final StringWriter sw = new StringWriter();
      -  421  0
                   PrintWriter pw = null;
      -  422   -
                   try {
      -  423  0
                       pw = new PrintWriter(sw);
      -  424  0
                       pw.format("%s:%n%n", header);
      -  425  0
                       final Enumeration<?> e = properties.propertyNames();
      -  426  0
                       while (e.hasMoreElements()) {
      -  427  0
                           final String key = (String) e.nextElement();
      -  428  0
                           if (key.contains("password")) {
      -  429  0
                               pw.format("%s='*****'%n", key);
      -  430   -
                           } else {
      -  431  0
                               final String value = properties.getProperty(key);
      -  432  0
                               if (value != null) {
      -  433  0
                                   pw.format("%s='%s'%n", key, value);
      -  434   -
                               }
      -  435   -
                           }
      -  436  0
                       }
      -  437  0
                       pw.flush();
      -  438  0
                       LOGGER.debug(sw.toString());
      -  439   -
                   } finally {
      -  440  0
                       if (pw != null) {
      -  441  0
                           pw.close();
      -  442   -
                       }
      -  443   -
                   }
      -  444   -
       
      -  445   -
               }
      -  446  3
           }
      -  447   -
       
      -  448   -
           /**
      -  449   -
            * Sets a property value.
      -  450   -
            *
      -  451   -
            * @param key the key for the property
      -  452   -
            * @param value the value for the property
      -  453   -
            */
      -  454   -
           public static void setString(String key, String value) {
      -  455  8
               localSettings.get().props.setProperty(key, value);
      -  456  8
               LOGGER.debug("Setting: {}='{}'", key, value);
      -  457  8
           }
      -  458   -
       
      -  459   -
           /**
      -  460   -
            * Sets a property value only if the value is not null.
      -  461   -
            *
      -  462   -
            * @param key the key for the property
      -  463   -
            * @param value the value for the property
      -  464   -
            */
      -  465   -
           public static void setStringIfNotNull(String key, String value) {
      -  466  1
               if (null != value) {
      -  467  0
                   setString(key, value);
      -  468   -
               }
      -  469  1
           }
      -  470   -
       
      -  471   -
           /**
      -  472   -
            * Sets a property value only if the value is not null and not empty.
      -  473   -
            *
      -  474   -
            * @param key the key for the property
      -  475   -
            * @param value the value for the property
      -  476   -
            */
      -  477   -
           public static void setStringIfNotEmpty(String key, String value) {
      -  478  1
               if (null != value && !value.isEmpty()) {
      -  479  0
                   setString(key, value);
      -  480   -
               }
      -  481  1
           }
      -  482   -
       
      -  483   -
           /**
      -  484   -
            * Sets a property value.
      -  485   -
            *
      -  486   -
            * @param key the key for the property
      -  487   -
            * @param value the value for the property
      -  488   -
            */
      -  489   -
           public static void setBoolean(String key, boolean value) {
      -  490  0
               setString(key, Boolean.toString(value));
      -  491  0
           }
      -  492   -
       
      -  493   -
           /**
      -  494   -
            * Sets a property value only if the value is not null.
      -  495   -
            *
      -  496   -
            * @param key the key for the property
      -  497   -
            * @param value the value for the property
      -  498   -
            */
      -  499   -
           public static void setBooleanIfNotNull(String key, Boolean value) {
      -  500  0
               if (null != value) {
      -  501  0
                   setBoolean(key, value);
      -  502   -
               }
      -  503  0
           }
      -  504   -
       
      -  505   -
           /**
      -  506   -
            * Sets a property value.
      -  507   -
            *
      -  508   -
            * @param key the key for the property
      -  509   -
            * @param value the value for the property
      -  510   -
            */
      -  511   -
           public static void setInt(String key, int value) {
      -  512  0
               localSettings.get().props.setProperty(key, String.valueOf(value));
      -  513  0
               LOGGER.debug("Setting: {}='{}'", key, value);
      -  514  0
           }
      -  515   -
       
      -  516   -
           /**
      -  517   -
            * Sets a property value only if the value is not null.
      -  518   -
            *
      -  519   -
            * @param key the key for the property
      -  520   -
            * @param value the value for the property
      -  521   -
            */
      -  522   -
           public static void setIntIfNotNull(String key, Integer value) {
      -  523  0
               if (null != value) {
      -  524  0
                   setInt(key, value);
      -  525   -
               }
      -  526  0
           }
      -  527   -
       
      -  528   -
           /**
      -  529   -
            * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties
      -  530   -
            * file.<br><br>
      -  531   -
            * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files.
      -  532   -
            *
      -  533   -
            * @param filePath the path to the properties file to merge.
      -  534   -
            * @throws FileNotFoundException is thrown when the filePath points to a non-existent file
      -  535   -
            * @throws IOException is thrown when there is an exception loading/merging the properties
      -  536   -
            */
      -  537   -
           public static void mergeProperties(File filePath) throws FileNotFoundException, IOException {
      -  538  0
               FileInputStream fis = null;
      -  539   -
               try {
      -  540  0
                   fis = new FileInputStream(filePath);
      -  541  0
                   mergeProperties(fis);
      -  542   -
               } finally {
      -  543  0
                   if (fis != null) {
      -  544   -
                       try {
      -  545  0
                           fis.close();
      -  546  0
                       } catch (IOException ex) {
      -  547  0
                           LOGGER.trace("close error", ex);
      -  548  0
                       }
      -  549   -
                   }
      -  550   -
               }
      -  551  0
           }
      -  552   -
       
      -  553   -
           /**
      -  554   -
            * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties
      -  555   -
            * file.<br><br>
      -  556   -
            * Note: even if using this method - system properties will be loaded before properties loaded from files.
      -  557   -
            *
      -  558   -
            * @param filePath the path to the properties file to merge.
      -  559   -
            * @throws FileNotFoundException is thrown when the filePath points to a non-existent file
      -  560   -
            * @throws IOException is thrown when there is an exception loading/merging the properties
      -  561   -
            */
      -  562   -
           public static void mergeProperties(String filePath) throws FileNotFoundException, IOException {
      -  563  1
               FileInputStream fis = null;
      -  564   -
               try {
      -  565  1
                   fis = new FileInputStream(filePath);
      -  566  1
                   mergeProperties(fis);
      -  567   -
               } finally {
      -  568  1
                   if (fis != null) {
      -  569   -
                       try {
      -  570  1
                           fis.close();
      -  571  0
                       } catch (IOException ex) {
      -  572  0
                           LOGGER.trace("close error", ex);
      -  573  1
                       }
      -  574   -
                   }
      -  575   -
               }
      -  576  1
           }
      -  577   -
       
      -  578   -
           /**
      -  579   -
            * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties
      -  580   -
            * file.<br><br>
      -  581   -
            * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files.
      -  582   -
            *
      -  583   -
            * @param stream an Input Stream pointing at a properties file to merge
      -  584   -
            * @throws IOException is thrown when there is an exception loading/merging the properties
      -  585   -
            */
      -  586   -
           public static void mergeProperties(InputStream stream) throws IOException {
      -  587  1
               localSettings.get().props.load(stream);
      -  588  1
               logProperties("Properties updated via merge", localSettings.get().props);
      -  589  1
           }
      -  590   -
       
      -  591   -
           /**
      -  592   -
            * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via
      -  593   -
            * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      -  594   -
            * configuration file.
      -  595   -
            *
      -  596   -
            * @param key the key to lookup within the properties file
      -  597   -
            * @return the property from the properties file converted to a File object
      -  598   -
            */
      -  599   -
           public static File getFile(String key) {
      -  600  0
               final String file = getString(key);
      -  601  0
               if (file == null) {
      -  602  0
                   return null;
      -  603   -
               }
      -  604  0
               return new File(file);
      -  605  
           }
      -  606   +  406  
       
      -  607   +  407  
           /**
      -  608   -
            * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via
      -  609   -
            * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      -  610   -
            * configuration file.
      -  611   +  408   +
            * Sets the instance of the Settings object to use in this thread.
      +  409  
            *
      +  410   +
            * @param instance the instance of the settings object to use in this thread
      +  411   +
            */
      +  412   +
           public static void setInstance(Settings instance) {
      +  413  0
               LOCAL_SETTINGS.set(instance);
      +  414  0
           }
      +  415   +
       
      +  416   +
           /**
      +  417   +
            * Logs the properties. This will not log any properties that contain 'password' in the key.
      +  418   +
            *
      +  419   +
            * @param header the header to print with the log message
      +  420   +
            * @param properties the properties to log
      +  421   +
            */
      +  422   +
           private static void logProperties(String header, Properties properties) {
      +  423  6
               if (LOGGER.isDebugEnabled()) {
      +  424  0
                   final StringWriter sw = new StringWriter();
      +  425  0
                   PrintWriter pw = null;
      +  426   +
                   try {
      +  427  0
                       pw = new PrintWriter(sw);
      +  428  0
                       pw.format("%s:%n%n", header);
      +  429  0
                       final Enumeration<?> e = properties.propertyNames();
      +  430  0
                       while (e.hasMoreElements()) {
      +  431  0
                           final String key = (String) e.nextElement();
      +  432  0
                           if (key.contains("password")) {
      +  433  0
                               pw.format("%s='*****'%n", key);
      +  434   +
                           } else {
      +  435  0
                               final String value = properties.getProperty(key);
      +  436  0
                               if (value != null) {
      +  437  0
                                   pw.format("%s='%s'%n", key, value);
      +  438   +
                               }
      +  439   +
                           }
      +  440  0
                       }
      +  441  0
                       pw.flush();
      +  442  0
                       LOGGER.debug(sw.toString());
      +  443   +
                   } finally {
      +  444  0
                       if (pw != null) {
      +  445  0
                           pw.close();
      +  446   +
                       }
      +  447   +
                   }
      +  448   +
       
      +  449   +
               }
      +  450  6
           }
      +  451   +
       
      +  452   +
           /**
      +  453   +
            * Sets a property value.
      +  454   +
            *
      +  455   +
            * @param key the key for the property
      +  456   +
            * @param value the value for the property
      +  457   +
            */
      +  458   +
           public static void setString(String key, String value) {
      +  459  16
               LOCAL_SETTINGS.get().props.setProperty(key, value);
      +  460  16
               LOGGER.debug("Setting: {}='{}'", key, value);
      +  461  16
           }
      +  462   +
       
      +  463   +
           /**
      +  464   +
            * Sets a property value only if the value is not null.
      +  465   +
            *
      +  466   +
            * @param key the key for the property
      +  467   +
            * @param value the value for the property
      +  468   +
            */
      +  469   +
           public static void setStringIfNotNull(String key, String value) {
      +  470  2
               if (null != value) {
      +  471  0
                   setString(key, value);
      +  472   +
               }
      +  473  2
           }
      +  474   +
       
      +  475   +
           /**
      +  476   +
            * Sets a property value only if the value is not null and not empty.
      +  477   +
            *
      +  478   +
            * @param key the key for the property
      +  479   +
            * @param value the value for the property
      +  480   +
            */
      +  481   +
           public static void setStringIfNotEmpty(String key, String value) {
      +  482  2
               if (null != value && !value.isEmpty()) {
      +  483  0
                   setString(key, value);
      +  484   +
               }
      +  485  2
           }
      +  486   +
       
      +  487   +
           /**
      +  488   +
            * Sets a property value.
      +  489   +
            *
      +  490   +
            * @param key the key for the property
      +  491   +
            * @param value the value for the property
      +  492   +
            */
      +  493   +
           public static void setBoolean(String key, boolean value) {
      +  494  0
               setString(key, Boolean.toString(value));
      +  495  0
           }
      +  496   +
       
      +  497   +
           /**
      +  498   +
            * Sets a property value only if the value is not null.
      +  499   +
            *
      +  500   +
            * @param key the key for the property
      +  501   +
            * @param value the value for the property
      +  502   +
            */
      +  503   +
           public static void setBooleanIfNotNull(String key, Boolean value) {
      +  504  0
               if (null != value) {
      +  505  0
                   setBoolean(key, value);
      +  506   +
               }
      +  507  0
           }
      +  508   +
       
      +  509   +
           /**
      +  510   +
            * Sets a property value.
      +  511   +
            *
      +  512   +
            * @param key the key for the property
      +  513   +
            * @param value the value for the property
      +  514   +
            */
      +  515   +
           public static void setInt(String key, int value) {
      +  516  0
               LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value));
      +  517  0
               LOGGER.debug("Setting: {}='{}'", key, value);
      +  518  0
           }
      +  519   +
       
      +  520   +
           /**
      +  521   +
            * Sets a property value only if the value is not null.
      +  522   +
            *
      +  523   +
            * @param key the key for the property
      +  524   +
            * @param value the value for the property
      +  525   +
            */
      +  526   +
           public static void setIntIfNotNull(String key, Integer value) {
      +  527  0
               if (null != value) {
      +  528  0
                   setInt(key, value);
      +  529   +
               }
      +  530  0
           }
      +  531   +
       
      +  532   +
           /**
      +  533   +
            * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties
      +  534   +
            * file.<br><br>
      +  535   +
            * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files.
      +  536   +
            *
      +  537   +
            * @param filePath the path to the properties file to merge.
      +  538   +
            * @throws FileNotFoundException is thrown when the filePath points to a non-existent file
      +  539   +
            * @throws IOException is thrown when there is an exception loading/merging the properties
      +  540   +
            */
      +  541   +
           public static void mergeProperties(File filePath) throws FileNotFoundException, IOException {
      +  542  0
               FileInputStream fis = null;
      +  543   +
               try {
      +  544  0
                   fis = new FileInputStream(filePath);
      +  545  0
                   mergeProperties(fis);
      +  546   +
               } finally {
      +  547  0
                   if (fis != null) {
      +  548   +
                       try {
      +  549  0
                           fis.close();
      +  550  0
                       } catch (IOException ex) {
      +  551  0
                           LOGGER.trace("close error", ex);
      +  552  0
                       }
      +  553   +
                   }
      +  554   +
               }
      +  555  0
           }
      +  556   +
       
      +  557   +
           /**
      +  558   +
            * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties
      +  559   +
            * file.<br><br>
      +  560   +
            * Note: even if using this method - system properties will be loaded before properties loaded from files.
      +  561   +
            *
      +  562   +
            * @param filePath the path to the properties file to merge.
      +  563   +
            * @throws FileNotFoundException is thrown when the filePath points to a non-existent file
      +  564   +
            * @throws IOException is thrown when there is an exception loading/merging the properties
      +  565   +
            */
      +  566   +
           public static void mergeProperties(String filePath) throws FileNotFoundException, IOException {
      +  567  2
               FileInputStream fis = null;
      +  568   +
               try {
      +  569  2
                   fis = new FileInputStream(filePath);
      +  570  2
                   mergeProperties(fis);
      +  571   +
               } finally {
      +  572  2
                   if (fis != null) {
      +  573   +
                       try {
      +  574  2
                           fis.close();
      +  575  0
                       } catch (IOException ex) {
      +  576  0
                           LOGGER.trace("close error", ex);
      +  577  2
                       }
      +  578   +
                   }
      +  579   +
               }
      +  580  2
           }
      +  581   +
       
      +  582   +
           /**
      +  583   +
            * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties
      +  584   +
            * file.<br><br>
      +  585   +
            * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files.
      +  586   +
            *
      +  587   +
            * @param stream an Input Stream pointing at a properties file to merge
      +  588   +
            * @throws IOException is thrown when there is an exception loading/merging the properties
      +  589   +
            */
      +  590   +
           public static void mergeProperties(InputStream stream) throws IOException {
      +  591  2
               LOCAL_SETTINGS.get().props.load(stream);
      +  592  2
               logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props);
      +  593  2
           }
      +  594   +
       
      +  595   +
           /**
      +  596   +
            * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via
      +  597   +
            * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      +  598   +
            * configuration file.
      +  599   +
            *
      +  600   +
            * @param key the key to lookup within the properties file
      +  601   +
            * @return the property from the properties file converted to a File object
      +  602   +
            */
      +  603   +
           public static File getFile(String key) {
      +  604  0
               final String file = getString(key);
      +  605  0
               if (file == null) {
      +  606  0
                   return null;
      +  607   +
               }
      +  608  0
               return new File(file);
      +  609   +
           }
      +  610   +
       
      +  611   +
           /**
       612   -
            * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the
      +
            * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via
       613   -
            * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this
      +
            * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained
       614   -
            * class.
      +
            * configuration file.
       615  
            *
       616   -
            * @param key the key to lookup within the properties file
      +
            * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the
       617   -
            * @return the property from the properties file converted to a File object
      +
            * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this
       618   -
            */
      +
            * class.
       619   +
            *
      +  620   +
            * @param key the key to lookup within the properties file
      +  621   +
            * @return the property from the properties file converted to a File object
      +  622   +
            */
      +  623  
           protected static File getDataFile(String key) {
      -  620  2
               final String file = getString(key);
      -  621  2
               LOGGER.debug("Settings.getDataFile() - file: '{}'", file);
      -  622  2
               if (file == null) {
      -  623  0
                   return null;
      -  624   +  624  4
               final String file = getString(key);
      +  625  4
               LOGGER.debug("Settings.getDataFile() - file: '{}'", file);
      +  626  4
               if (file == null) {
      +  627  0
                   return null;
      +  628  
               }
      -  625  2
               if (file.startsWith("[JAR]")) {
      -  626  0
                   LOGGER.debug("Settings.getDataFile() - transforming filename");
      -  627  0
                   final File jarPath = getJarPath();
      -  628  0
                   LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString());
      -  629  0
                   final File retVal = new File(jarPath, file.substring(6));
      -  630  0
                   LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString());
      -  631  0
                   return retVal;
      -  632   -
               }
      -  633  2
               return new File(file);
      -  634   -
           }
      -  635   -
       
      +  629  4
               if (file.startsWith("[JAR]")) {
      +  630  0
                   LOGGER.debug("Settings.getDataFile() - transforming filename");
      +  631  0
                   final File jarPath = getJarPath();
      +  632  0
                   LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString());
      +  633  0
                   final File retVal = new File(jarPath, file.substring(6));
      +  634  0
                   LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString());
      +  635  0
                   return retVal;
       636   -
           /**
      -  637   -
            * Attempts to retrieve the folder containing the Jar file containing the Settings class.
      +
               }
      +  637  4
               return new File(file);
       638   -
            *
      +
           }
       639   -
            * @return a File object
      +
       
       640   -
            */
      +
           /**
       641   -
           private static File getJarPath() {
      -  642  0
               final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath();
      -  643  0
               String decodedPath = ".";
      +
            * Attempts to retrieve the folder containing the Jar file containing the Settings class.
      +  642   +
            *
      +  643   +
            * @return a File object
       644   +
            */
      +  645   +
           private static File getJarPath() {
      +  646  0
               final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath();
      +  647  0
               String decodedPath = ".";
      +  648  
               try {
      -  645  0
                   decodedPath = URLDecoder.decode(jarPath, "UTF-8");
      -  646  0
               } catch (UnsupportedEncodingException ex) {
      -  647  0
                   LOGGER.trace("", ex);
      -  648  0
               }
      -  649   -
       
      -  650  0
               final File path = new File(decodedPath);
      -  651  0
               if (path.getName().toLowerCase().endsWith(".jar")) {
      -  652  0
                   return path.getParentFile();
      +  649  0
                   decodedPath = URLDecoder.decode(jarPath, "UTF-8");
      +  650  0
               } catch (UnsupportedEncodingException ex) {
      +  651  0
                   LOGGER.trace("", ex);
      +  652  0
               }
       653   -
               } else {
      -  654  0
                   return new File(".");
      -  655   -
               }
      -  656   -
           }
      +
       
      +  654  0
               final File path = new File(decodedPath);
      +  655  0
               if (path.getName().toLowerCase().endsWith(".jar")) {
      +  656  0
                   return path.getParentFile();
       657   -
       
      -  658   -
           /**
      +
               } else {
      +  658  0
                   return new File(".");
       659   -
            * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value
      +
               }
       660   -
            * argument - this method will return the value from the system properties before the values in the contained configuration
      +
           }
       661   -
            * file.
      +
       
       662   -
            *
      +
           /**
       663   -
            * @param key the key to lookup within the properties file
      -  664   -
            * @param defaultValue the default value for the requested property
      -  665   -
            * @return the property from the properties file
      -  666   -
            */
      -  667   -
           public static String getString(String key, String defaultValue) {
      -  668  6
               final String str = System.getProperty(key, localSettings.get().props.getProperty(key, defaultValue));
      -  669  6
               return str;
      -  670   -
           }
      -  671   -
       
      -  672   -
           /**
      -  673   -
            * A reference to the temporary directory; used incase it needs to be deleted during cleanup.
      -  674   -
            */
      -  675  1
           private static File tempDirectory = null;
      -  676   -
       
      -  677   -
           /**
      -  678   -
            * Returns the temporary directory.
      -  679   -
            *
      -  680   -
            * @return the temporary directory
      -  681   -
            * @throws java.io.IOException thrown if the temporary directory does not exist and cannot be created
      -  682   -
            */
      -  683   -
           public static File getTempDirectory() throws IOException {
      -  684  2
               final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp");
      -  685  2
               if (!tmpDir.exists() && !tmpDir.mkdirs()) {
      -  686  0
                   final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath());
      -  687  0
                   throw new IOException(msg);
      -  688   -
               }
      -  689  2
               tempDirectory = tmpDir;
      -  690  2
               return tmpDir;
      -  691   -
           }
      -  692   -
       
      -  693   -
           /**
      -  694  
            * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value
      -  695   +  664  
            * argument - this method will return the value from the system properties before the values in the contained configuration
      -  696   +  665  
            * file.
      +  666   +
            *
      +  667   +
            * @param key the key to lookup within the properties file
      +  668   +
            * @param defaultValue the default value for the requested property
      +  669   +
            * @return the property from the properties file
      +  670   +
            */
      +  671   +
           public static String getString(String key, String defaultValue) {
      +  672  12
               final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue));
      +  673  12
               return str;
      +  674   +
           }
      +  675   +
       
      +  676   +
           /**
      +  677   +
            * A reference to the temporary directory; used incase it needs to be deleted during cleanup.
      +  678   +
            */
      +  679  2
           private static File tempDirectory = null;
      +  680   +
       
      +  681   +
           /**
      +  682   +
            * Returns the temporary directory.
      +  683   +
            *
      +  684   +
            * @return the temporary directory
      +  685   +
            * @throws java.io.IOException thrown if the temporary directory does not exist and cannot be created
      +  686   +
            */
      +  687   +
           public static File getTempDirectory() throws IOException {
      +  688  4
               final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp");
      +  689  4
               if (!tmpDir.exists() && !tmpDir.mkdirs()) {
      +  690  0
                   final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath());
      +  691  0
                   throw new IOException(msg);
      +  692   +
               }
      +  693  4
               tempDirectory = tmpDir;
      +  694  4
               return tmpDir;
      +  695   +
           }
      +  696   +
       
       697   -
            *
      +
           /**
       698   -
            * @param key the key to lookup within the properties file
      +
            * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value
       699   -
            * @return the property from the properties file
      +
            * argument - this method will return the value from the system properties before the values in the contained configuration
       700   -
            */
      +
            * file.
       701   -
           public static String getString(String key) {
      -  702  19
               return System.getProperty(key, localSettings.get().props.getProperty(key));
      +
            *
      +  702   +
            * @param key the key to lookup within the properties file
       703   -
           }
      +
            * @return the property from the properties file
       704   -
       
      +
            */
       705   -
           /**
      -  706   -
            * Removes a property from the local properties collection. This is mainly used in test cases.
      +
           public static String getString(String key) {
      +  706  38
               return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key));
       707   -
            *
      +
           }
       708   -
            * @param key the property key to remove
      +
       
       709   -
            */
      +
           /**
       710   -
           public static void removeProperty(String key) {
      -  711  1
               localSettings.get().props.remove(key);
      -  712  1
           }
      +
            * Removes a property from the local properties collection. This is mainly used in test cases.
      +  711   +
            *
      +  712   +
            * @param key the property key to remove
       713   -
       
      +
            */
       714   -
           /**
      -  715   -
            * Returns an int value from the properties file. If the value was specified as a system property or passed in via the
      -  716   -
            * -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      +
           public static void removeProperty(String key) {
      +  715  2
               LOCAL_SETTINGS.get().props.remove(key);
      +  716  2
           }
       717   -
            * configuration file.
      +
       
       718   -
            *
      +
           /**
       719   -
            * @param key the key to lookup within the properties file
      -  720   -
            * @return the property from the properties file
      -  721   -
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      -  722   -
            */
      -  723   -
           public static int getInt(String key) throws InvalidSettingException {
      -  724   -
               try {
      -  725  1
                   return Integer.parseInt(Settings.getString(key));
      -  726  0
               } catch (NumberFormatException ex) {
      -  727  0
                   throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex);
      -  728   -
               }
      -  729   -
           }
      -  730   -
       
      -  731   -
           /**
      -  732  
            * Returns an int value from the properties file. If the value was specified as a system property or passed in via the
      +  720   +
            * -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      +  721   +
            * configuration file.
      +  722   +
            *
      +  723   +
            * @param key the key to lookup within the properties file
      +  724   +
            * @return the property from the properties file
      +  725   +
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      +  726   +
            */
      +  727   +
           public static int getInt(String key) throws InvalidSettingException {
      +  728   +
               try {
      +  729  2
                   return Integer.parseInt(Settings.getString(key));
      +  730  0
               } catch (NumberFormatException ex) {
      +  731  0
                   throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex);
      +  732   +
               }
       733   -
            * -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      +
           }
       734   -
            * configuration file.
      +
       
       735   -
            *
      +
           /**
       736   -
            * @param key the key to lookup within the properties file
      +
            * Returns an int value from the properties file. If the value was specified as a system property or passed in via the
       737   -
            * @param defaultValue the default value to return
      -  738   -
            * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to
      -  739   -
            * an integer
      -  740   -
            */
      -  741   -
           public static int getInt(String key, int defaultValue) {
      -  742   -
               int value;
      -  743   -
               try {
      -  744  1
                   value = Integer.parseInt(Settings.getString(key));
      -  745  1
               } catch (NumberFormatException ex) {
      -  746  1
                   if (!Settings.getString(key, "").isEmpty()) {
      -  747  1
                       LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue);
      -  748   -
                   }
      -  749  1
                   value = defaultValue;
      -  750  0
               }
      -  751  1
               return value;
      -  752   -
           }
      -  753   -
       
      -  754   -
           /**
      -  755   -
            * Returns a long value from the properties file. If the value was specified as a system property or passed in via the
      -  756  
            * -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      -  757   +  738  
            * configuration file.
      -  758   +  739  
            *
      -  759   +  740  
            * @param key the key to lookup within the properties file
      -  760   -
            * @return the property from the properties file
      -  761   -
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      -  762   +  741   +
            * @param defaultValue the default value to return
      +  742   +
            * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to
      +  743   +
            * an integer
      +  744  
            */
      -  763   -
           public static long getLong(String key) throws InvalidSettingException {
      -  764   +  745   +
           public static int getInt(String key, int defaultValue) {
      +  746   +
               int value;
      +  747  
               try {
      -  765  1
                   return Long.parseLong(Settings.getString(key));
      -  766  0
               } catch (NumberFormatException ex) {
      -  767  0
                   throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex);
      +  748  2
                   value = Integer.parseInt(Settings.getString(key));
      +  749  2
               } catch (NumberFormatException ex) {
      +  750  2
                   if (!Settings.getString(key, "").isEmpty()) {
      +  751  2
                       LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue);
      +  752   +
                   }
      +  753  2
                   value = defaultValue;
      +  754  0
               }
      +  755  2
               return value;
      +  756   +
           }
      +  757   +
       
      +  758   +
           /**
      +  759   +
            * Returns a long value from the properties file. If the value was specified as a system property or passed in via the
      +  760   +
            * -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      +  761   +
            * configuration file.
      +  762   +
            *
      +  763   +
            * @param key the key to lookup within the properties file
      +  764   +
            * @return the property from the properties file
      +  765   +
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      +  766   +
            */
      +  767   +
           public static long getLong(String key) throws InvalidSettingException {
       768   -
               }
      -  769   -
           }
      -  770   -
       
      -  771   -
           /**
      +
               try {
      +  769  2
                   return Long.parseLong(Settings.getString(key));
      +  770  0
               } catch (NumberFormatException ex) {
      +  771  0
                   throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex);
       772   -
            * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the
      +
               }
       773   -
            * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the
      +
           }
       774   -
            * contained configuration file.
      +
       
       775   -
            *
      +
           /**
       776   -
            * @param key the key to lookup within the properties file
      -  777   -
            * @return the property from the properties file
      -  778   -
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      -  779   -
            */
      -  780   -
           public static boolean getBoolean(String key) throws InvalidSettingException {
      -  781  1
               return Boolean.parseBoolean(Settings.getString(key));
      -  782   -
           }
      -  783   -
       
      -  784   -
           /**
      -  785  
            * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the
      -  786   +  777  
            * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the
      -  787   +  778  
            * contained configuration file.
      -  788   +  779  
            *
      -  789   +  780  
            * @param key the key to lookup within the properties file
      -  790   -
            * @param defaultValue the default value to return if the setting does not exist
      -  791   +  781  
            * @return the property from the properties file
      -  792   +  782  
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      +  783   +
            */
      +  784   +
           public static boolean getBoolean(String key) throws InvalidSettingException {
      +  785  2
               return Boolean.parseBoolean(Settings.getString(key));
      +  786   +
           }
      +  787   +
       
      +  788   +
           /**
      +  789   +
            * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the
      +  790   +
            * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the
      +  791   +
            * contained configuration file.
      +  792   +
            *
       793   -
            */
      +
            * @param key the key to lookup within the properties file
       794   -
           public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException {
      -  795  1
               return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue)));
      +
            * @param defaultValue the default value to return if the setting does not exist
      +  795   +
            * @return the property from the properties file
       796   -
           }
      +
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
       797   -
       
      +
            */
       798   -
           /**
      -  799   -
            * Returns a connection string from the configured properties. If the connection string contains a %s, this method will
      +
           public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException {
      +  799  2
               return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue)));
       800   -
            * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not
      +
           }
       801   -
            * exists it will be created.
      -  802   -
            *
      -  803   -
            * @param connectionStringKey the property file key for the connection string
      -  804   -
            * @param dbFileNameKey the settings key for the db filename
      -  805   -
            * @return the connection string
      -  806   -
            * @throws IOException thrown the data directory cannot be created
      -  807   -
            * @throws InvalidSettingException thrown if there is an invalid setting
      -  808   -
            */
      -  809   -
           public static String getConnectionString(String connectionStringKey, String dbFileNameKey)
      -  810   -
                   throws IOException, InvalidSettingException {
      -  811  2
               final String connStr = Settings.getString(connectionStringKey);
      -  812  2
               if (connStr == null) {
      -  813  1
                   final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey);
      -  814  1
                   throw new InvalidSettingException(msg);
      -  815   -
               }
      -  816  1
               if (connStr.contains("%s")) {
      -  817  1
                   final File directory = getDataDirectory();
      -  818  1
                   String fileName = null;
      -  819  1
                   if (dbFileNameKey != null) {
      -  820  1
                       fileName = Settings.getString(dbFileNameKey);
      -  821   -
                   }
      -  822  1
                   if (fileName == null) {
      -  823  0
                       final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.",
      -  824   -
                               dbFileNameKey);
      -  825  0
                       throw new InvalidSettingException(msg);
      -  826   -
                   }
      -  827  1
                   if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) {
      -  828  1
                       fileName = fileName.substring(0, fileName.length() - 6);
      -  829   -
                   }
      -  830   -
                   // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed
      -  831  1
                   final File dbFile = new File(directory, fileName);
      -  832  1
                   final String cString = String.format(connStr, dbFile.getCanonicalPath());
      -  833  1
                   LOGGER.debug("Connection String: '{}'", cString);
      -  834  1
                   return cString;
      -  835   -
               }
      -  836  0
               return connStr;
      -  837   -
           }
      -  838  
       
      -  839   +  802  
           /**
      -  840   -
            * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the
      -  841   -
            * embedded H2 database. This is public solely for some unit tests; otherwise this should be private.
      -  842   +  803   +
            * Returns a connection string from the configured properties. If the connection string contains a %s, this method will
      +  804   +
            * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not
      +  805   +
            * exists it will be created.
      +  806  
            *
      -  843   -
            * @return the data directory to store data files
      -  844   -
            * @throws IOException is thrown if an IOException occurs of course...
      -  845   +  807   +
            * @param connectionStringKey the property file key for the connection string
      +  808   +
            * @param dbFileNameKey the settings key for the db filename
      +  809   +
            * @return the connection string
      +  810   +
            * @throws IOException thrown the data directory cannot be created
      +  811   +
            * @throws InvalidSettingException thrown if there is an invalid setting
      +  812  
            */
      -  846   -
           public static File getDataDirectory() throws IOException {
      -  847  1
               final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY);
      -  848  1
               if (path.exists() || path.mkdirs()) {
      -  849  1
                   return path;
      -  850   +  813   +
           public static String getConnectionString(String connectionStringKey, String dbFileNameKey)
      +  814   +
                   throws IOException, InvalidSettingException {
      +  815  4
               final String connStr = Settings.getString(connectionStringKey);
      +  816  4
               if (connStr == null) {
      +  817  2
                   final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey);
      +  818  2
                   throw new InvalidSettingException(msg);
      +  819  
               }
      -  851  0
               throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath()));
      -  852   +  820  2
               if (connStr.contains("%s")) {
      +  821  2
                   final File directory = getDataDirectory();
      +  822  2
                   String fileName = null;
      +  823  2
                   if (dbFileNameKey != null) {
      +  824  2
                       fileName = Settings.getString(dbFileNameKey);
      +  825   +
                   }
      +  826  2
                   if (fileName == null) {
      +  827  0
                       final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.",
      +  828   +
                               dbFileNameKey);
      +  829  0
                       throw new InvalidSettingException(msg);
      +  830   +
                   }
      +  831  2
                   if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) {
      +  832  2
                       fileName = fileName.substring(0, fileName.length() - 6);
      +  833   +
                   }
      +  834   +
                   // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed
      +  835  2
                   final File dbFile = new File(directory, fileName);
      +  836  2
                   final String cString = String.format(connStr, dbFile.getCanonicalPath());
      +  837  2
                   LOGGER.debug("Connection String: '{}'", cString);
      +  838  2
                   return cString;
      +  839   +
               }
      +  840  0
               return connStr;
      +  841  
           }
      -  853   +  842   +
       
      +  843   +
           /**
      +  844   +
            * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the
      +  845   +
            * embedded H2 database. This is public solely for some unit tests; otherwise this should be private.
      +  846   +
            *
      +  847   +
            * @return the data directory to store data files
      +  848   +
            * @throws IOException is thrown if an IOException occurs of course...
      +  849   +
            */
      +  850   +
           public static File getDataDirectory() throws IOException {
      +  851  2
               final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY);
      +  852  2
               if (path.exists() || path.mkdirs()) {
      +  853  2
                   return path;
      +  854   +
               }
      +  855  0
               throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath()));
      +  856   +
           }
      +  857  
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFactory.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFactory.html index 3dff6e5f2..382e4075d 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFactory.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFactory.html @@ -292,6 +292,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFailureException.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFailureException.html index 02acfe045..9936d3fa2 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFailureException.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFailureException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-utils/dependency-analysis.html b/dependency-check-utils/dependency-analysis.html index 1f539f023..6090f7431 100644 --- a/dependency-check-utils/dependency-analysis.html +++ b/dependency-check-utils/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Dependencies Report @@ -52,7 +52,7 @@ @@ -200,9 +200,6 @@ developed using - - - built on cloudbees @@ -227,7 +224,7 @@ commons-io commons-io -2.4 +2.5 compile jar diff --git a/dependency-check-utils/dependency-updates-report.html b/dependency-check-utils/dependency-updates-report.html index 539a824cd..532360e06 100644 --- a/dependency-check-utils/dependency-updates-report.html +++ b/dependency-check-utils/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Dependency Updates Report @@ -52,7 +52,7 @@ @@ -200,9 +200,6 @@ developed using - - - built on cloudbees @@ -218,7 +215,7 @@ # of dependencies using the latest version available -21 +22 # of dependencies where the next version available is smaller than an incremental version update @@ -226,11 +223,11 @@ # of dependencies where the next version available is an incremental version update -3 +1 # of dependencies where the next version available is a minor version update -6 +7 # of dependencies where the next version available is a major version update @@ -338,7 +335,7 @@ commons-io commons-io -2.4 +2.5 jar @@ -362,7 +359,7 @@ org.apache.ant ant -1.9.6 +1.9.7 jar @@ -374,7 +371,7 @@ org.apache.ant ant-testutil -1.9.6 +1.9.7 jar @@ -455,39 +452,39 @@ 4.8.0 5.0.0 - + org.apache.maven maven-core -3.3.3 +3.3.9 jar -3.3.9 + - + org.apache.maven maven-plugin-api -3.3.3 +3.3.9 jar -3.3.9 + - + org.apache.maven maven-settings -3.3.3 +3.3.9 jar -3.3.9 + @@ -563,7 +560,7 @@ - + org.jmockit jmockit 1.22 @@ -572,18 +569,18 @@ jar - +1.23 - + org.jsoup jsoup -1.8.3 +1.9.1 jar - +1.9.2 @@ -738,7 +735,7 @@ jar Newer versions -1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191 Latest Minor +1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191
      1.4.192 Latest Minor

      com.sun.mail:mailapi

      @@ -828,7 +825,7 @@ - + @@ -876,7 +873,7 @@ - + @@ -900,7 +897,7 @@ - + @@ -987,7 +984,7 @@ -
      commons-io
      Current Version2.4
      2.5
      Scope
      ant
      Current Version1.9.6
      1.9.7
      Scope
      ant-testutil
      Current Version1.9.6
      1.9.7
      Scope
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-core

      @@ -1014,7 +1011,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1041,7 +1038,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1068,13 +1065,13 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.maven:maven-core

      - + @@ -1083,7 +1080,7 @@ - + @@ -1092,16 +1089,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-core
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-plugin-api

      - + @@ -1110,7 +1104,7 @@ - + @@ -1119,16 +1113,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-plugin-api
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-settings

      - + @@ -1137,7 +1128,7 @@ - + @@ -1146,10 +1137,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-settings
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven.plugin-testing:maven-plugin-testing-harness

      @@ -1299,7 +1287,7 @@
      - + @@ -1317,13 +1305,16 @@ -
      Status No newer versions available.
       There is at least one newer minor version available. Minor updates are sometimes passive.
      Group Id org.jmockit
      Typejar
      +jar + +Newer versions +1.23 Next Minor
      1.24 Latest Minor

      org.jsoup:jsoup

      - + @@ -1332,7 +1323,7 @@ - + @@ -1341,7 +1332,10 @@ -
      Status No newer versions available.
       There is at least one newer incremental version available. Incremental updates are typically passive.
      Group Id org.jsoup
      jsoup
      Current Version1.8.3
      1.9.1
      Scope
      Typejar
      +jar + +Newer versions +1.9.2 Next Incremental

      org.slf4j:slf4j-api

      diff --git a/dependency-check-utils/findbugs.html b/dependency-check-utils/findbugs.html index aa435db5d..552106568 100644 --- a/dependency-check-utils/findbugs.html +++ b/dependency-check-utils/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-ant – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ @@ -200,9 +200,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/index.html b/dependency-check-utils/index.html index 597852297..e44af2a6f 100644 --- a/dependency-check-utils/index.html +++ b/dependency-check-utils/index.html @@ -1,13 +1,13 @@ - + dependency-check-ant – About @@ -52,7 +52,7 @@ @@ -123,9 +123,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/integration.html b/dependency-check-utils/integration.html index a054b5cb0..c32bf4ced 100644 --- a/dependency-check-utils/integration.html +++ b/dependency-check-utils/integration.html @@ -1,13 +1,13 @@ - + dependency-check-ant – CI Management @@ -52,7 +52,7 @@ @@ -172,9 +172,6 @@ developed using - - - built on cloudbees @@ -185,11 +182,11 @@

      Overview

      -

      This project uses Continuous Integration System.

      +

      This project uses Travis CI.

      Access

      The following is a link to the continuous integration system used by the project:

      -
      +

      Notifiers

      No notifiers are defined. Please check back at a later date.

      diff --git a/dependency-check-utils/issue-tracking.html b/dependency-check-utils/issue-tracking.html index 7007d4e03..f3d4e2626 100644 --- a/dependency-check-utils/issue-tracking.html +++ b/dependency-check-utils/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Issue Management @@ -52,7 +52,7 @@ @@ -172,9 +172,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/license.html b/dependency-check-utils/license.html index 0c747f420..d651366f1 100644 --- a/dependency-check-utils/license.html +++ b/dependency-check-utils/license.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Licenses @@ -52,7 +52,7 @@ @@ -172,9 +172,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/mail-lists.html b/dependency-check-utils/mail-lists.html index 346474cf8..a58ff0a0f 100644 --- a/dependency-check-utils/mail-lists.html +++ b/dependency-check-utils/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Mailing Lists @@ -52,7 +52,7 @@ @@ -172,9 +172,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/plugin-updates-report.html b/dependency-check-utils/plugin-updates-report.html index 1b6100514..05ba5c7a9 100644 --- a/dependency-check-utils/plugin-updates-report.html +++ b/dependency-check-utils/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Plugin Updates Report @@ -52,7 +52,7 @@ @@ -200,9 +200,6 @@ developed using - - - built on cloudbees @@ -218,7 +215,7 @@ - + @@ -234,7 +231,7 @@ - + @@ -356,7 +353,7 @@ - + @@ -386,7 +383,7 @@ - + @@ -396,21 +393,21 @@ - + - + - - + + @@ -622,7 +619,7 @@ -
      # of plugins using the latest version available19
      18
      # of plugins where the next version available is smaller than an incremental version update
      # of plugins where the next version available is a major version update0
      1
      # of plugins where a dependencies section containes a dependency with an updated version org.apache.maven.plugins maven-jar-plugin2.63.0.0 org.apache.maven.plugins maven-resources-plugin2.73.0.0 org.apache.maven.plugins maven-site-plugin3.53.5.1
      org.apache.maven.plugins maven-source-plugin2.42.4 3.0.0
      maven-jar-plugin
      Current Version2.6
      +3.0.0

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -667,7 +664,7 @@ -
      maven-resources-plugin
      Current Version2.7
      +3.0.0

      Plugin org.apache.maven.plugins:maven-site-plugin

      @@ -682,13 +679,13 @@ -
      maven-site-plugin
      Current Version3.5
      +3.5.1

      Plugin org.apache.maven.plugins:maven-source-plugin

      - + @@ -697,7 +694,10 @@ -
      Status No newer versions available.
       There is at least one newer major version available. Major updates are rarely passive.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      +2.4 + +Newer versions +3.0.0 Next Major

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-utils/project-info.html b/dependency-check-utils/project-info.html index cf96b37b9..28656dd9e 100644 --- a/dependency-check-utils/project-info.html +++ b/dependency-check-utils/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Information @@ -52,7 +52,7 @@ @@ -172,9 +172,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/project-reports.html b/dependency-check-utils/project-reports.html index 9330bf07f..b084c65d8 100644 --- a/dependency-check-utils/project-reports.html +++ b/dependency-check-utils/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Generated Reports @@ -52,7 +52,7 @@ @@ -200,9 +200,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/project-summary.html b/dependency-check-utils/project-summary.html index a788242bc..51a51f50e 100644 --- a/dependency-check-utils/project-summary.html +++ b/dependency-check-utils/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Summary @@ -52,7 +52,7 @@ @@ -172,9 +172,6 @@ developed using - - - built on cloudbees @@ -226,7 +223,7 @@ - + diff --git a/dependency-check-utils/source-repository.html b/dependency-check-utils/source-repository.html index 35af5d0f7..abecdb61a 100644 --- a/dependency-check-utils/source-repository.html +++ b/dependency-check-utils/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Source Code Management @@ -52,7 +52,7 @@ @@ -172,9 +172,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/surefire-report.html b/dependency-check-utils/surefire-report.html index 73fd4fbfa..321891b7b 100644 --- a/dependency-check-utils/surefire-report.html +++ b/dependency-check-utils/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Surefire Report @@ -52,7 +52,7 @@ @@ -200,9 +200,6 @@ developed using - - - built on cloudbees @@ -247,7 +244,7 @@ function toggleDisplay(elementId) { -
      dependency-check-utils
      Version1.3.6
      1.4.0
      Type jar
      0 0 100%0.616

      +0.511

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -268,7 +265,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.616
      +0.511

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.utils

      @@ -290,7 +287,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.539 +0.385 DownloaderTest @@ -299,7 +296,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.001 +0.002 ExpectedOjectInputStreamTest @@ -308,7 +305,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.005 +0.053 FileUtilsTest @@ -317,7 +314,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.071 +0.068 SettingsTest @@ -326,7 +323,7 @@ function toggleDisplay(elementId) { 0 0 100% -0

      +0.003

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -336,11 +333,11 @@ function toggleDisplay(elementId) { testGetChecksum_NoSuchAlgorithm -0.456 +0.333 testGetChecksum -0.006 +0.005 testGetMD5Checksum @@ -356,7 +353,7 @@ function toggleDisplay(elementId) { testGetSHA1Checksum -0.002
      +0.001

      DownloaderTest

      @@ -370,11 +367,11 @@ function toggleDisplay(elementId) { - + -
      testResolveClassException0
      0.048
      testResolveClass0
      +0.001

      FileUtilsTest

      @@ -385,7 +382,7 @@ function toggleDisplay(elementId) { -
      testDelete0.07
      +0.066

      SettingsTest

      diff --git a/dependency-check-utils/taglist.html b/dependency-check-utils/taglist.html index df1a65e0b..9af72b884 100644 --- a/dependency-check-utils/taglist.html +++ b/dependency-check-utils/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Tag List report @@ -52,7 +52,7 @@ @@ -200,9 +200,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/team-list.html b/dependency-check-utils/team-list.html index 7fa192808..91b684e54 100644 --- a/dependency-check-utils/team-list.html +++ b/dependency-check-utils/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Team @@ -52,7 +52,7 @@ @@ -172,9 +172,6 @@ developed using - - - built on cloudbees diff --git a/dependency-check-utils/xref-test/index.html b/dependency-check-utils/xref-test/index.html index cde2313bf..82d4c0a26 100644 --- a/dependency-check-utils/xref-test/index.html +++ b/dependency-check-utils/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Utils 1.3.6 Reference + Dependency-Check Utils 1.4.0 Reference diff --git a/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-frame.html b/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-frame.html index 7437a6817..03cc3cb53 100644 --- a/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-frame.html +++ b/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Utils 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-summary.html index d6d86b9d1..67f115720 100644 --- a/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Utils 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-utils/xref-test/overview-frame.html b/dependency-check-utils/xref-test/overview-frame.html index 7f5f75f75..fa6fa0f94 100644 --- a/dependency-check-utils/xref-test/overview-frame.html +++ b/dependency-check-utils/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.3.6 Reference + Dependency-Check Utils 1.4.0 Reference diff --git a/dependency-check-utils/xref-test/overview-summary.html b/dependency-check-utils/xref-test/overview-summary.html index 9d7f20b53..b26443869 100644 --- a/dependency-check-utils/xref-test/overview-summary.html +++ b/dependency-check-utils/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.3.6 Reference + Dependency-Check Utils 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Utils 1.3.6 Reference

      +

      Dependency-Check Utils 1.4.0 Reference

      diff --git a/dependency-check-utils/xref/index.html b/dependency-check-utils/xref/index.html index cde2313bf..82d4c0a26 100644 --- a/dependency-check-utils/xref/index.html +++ b/dependency-check-utils/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Utils 1.3.6 Reference + Dependency-Check Utils 1.4.0 Reference diff --git a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Settings.html b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Settings.html index 7d94000a1..f53fda40e 100644 --- a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Settings.html +++ b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Settings.html @@ -198,667 +198,671 @@ 190 */191publicstaticfinal String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled"; 192/** -193 * The properties key for whether the Archive analyzer is enabled. +193 * The properties key for whether experimental analyzers are loaded.194 */ -195publicstaticfinal String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled"; +195publicstaticfinal String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled"; 196/** -197 * The properties key for whether the node.js package analyzer is enabled. +197 * The properties key for whether the Archive analyzer is enabled.198 */ -199publicstaticfinal String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled"; +199publicstaticfinal String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled"; 200/** -201 * The properties key for whether the composer lock file analyzer is enabled. +201 * The properties key for whether the node.js package analyzer is enabled.202 */ -203publicstaticfinal String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled"; +203publicstaticfinal String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled"; 204/** -205 * The properties key for whether the Python Distribution analyzer is enabled. +205 * The properties key for whether the composer lock file analyzer is enabled.206 */ -207publicstaticfinal String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled"; +207publicstaticfinal String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled"; 208/** -209 * The properties key for whether the Python Package analyzer is enabled. +209 * The properties key for whether the Python Distribution analyzer is enabled.210 */ -211publicstaticfinal String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled"; +211publicstaticfinal String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled"; 212/** -213 * The properties key for whether the Ruby Gemspec Analyzer is enabled. +213 * The properties key for whether the Python Package analyzer is enabled.214 */ -215publicstaticfinal String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled"; +215publicstaticfinal String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled"; 216/** -217 * The properties key for whether the Autoconf analyzer is enabled. +217 * The properties key for whether the Ruby Gemspec Analyzer is enabled.218 */ -219publicstaticfinal String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled"; +219publicstaticfinal String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled"; 220/** -221 * The properties key for whether the CMake analyzer is enabled. +221 * The properties key for whether the Autoconf analyzer is enabled.222 */ -223publicstaticfinal String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled"; +223publicstaticfinal String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled"; 224/** -225 * The properties key for whether the Ruby Bundler Audit analyzer is enabled. +225 * The properties key for whether the CMake analyzer is enabled.226 */ -227publicstaticfinal String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled"; +227publicstaticfinal String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled"; 228/** -229 * The properties key for whether the .NET Assembly analyzer is enabled. +229 * The properties key for whether the Ruby Bundler Audit analyzer is enabled.230 */ -231publicstaticfinal String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled"; +231publicstaticfinal String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled"; 232/** -233 * The properties key for whether the .NET Nuspec analyzer is enabled. +233 * The properties key for whether the .NET Assembly analyzer is enabled.234 */ -235publicstaticfinal String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled"; +235publicstaticfinal String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled"; 236/** -237 * The properties key for whether the Nexus analyzer is enabled. +237 * The properties key for whether the .NET Nuspec analyzer is enabled.238 */ -239publicstaticfinal String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled"; +239publicstaticfinal String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled"; 240/** -241 * The properties key for the Nexus search URL. +241 * The properties key for whether the Nexus analyzer is enabled.242 */ -243publicstaticfinal String ANALYZER_NEXUS_URL = "analyzer.nexus.url"; +243publicstaticfinal String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled"; 244/** -245 * The properties key for using the proxy to reach Nexus. +245 * The properties key for the Nexus search URL.246 */ -247publicstaticfinal String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy"; +247publicstaticfinal String ANALYZER_NEXUS_URL = "analyzer.nexus.url"; 248/** -249 * The properties key for whether the Central analyzer is enabled. +249 * The properties key for using the proxy to reach Nexus.250 */ -251publicstaticfinal String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled"; +251publicstaticfinal String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy"; 252/** -253 * The properties key for whether the OpenSSL analyzer is enabled. +253 * The properties key for whether the Central analyzer is enabled.254 */ -255publicstaticfinal String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled"; +255publicstaticfinal String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled"; 256/** -257 * The properties key for the Central search URL. +257 * The properties key for whether the OpenSSL analyzer is enabled.258 */ -259publicstaticfinal String ANALYZER_CENTRAL_URL = "analyzer.central.url"; +259publicstaticfinal String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled"; 260/** -261 * The path to mono, if available. +261 * The properties key for the Central search URL.262 */ -263publicstaticfinal String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path"; +263publicstaticfinal String ANALYZER_CENTRAL_URL = "analyzer.central.url"; 264/** -265 * The path to bundle-audit, if available. +265 * The path to mono, if available.266 */ -267publicstaticfinal String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path"; +267publicstaticfinal String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path"; 268/** -269 * The additional configured zip file extensions, if available. +269 * The path to bundle-audit, if available.270 */ -271publicstaticfinal String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip"; +271publicstaticfinal String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path"; 272/** -273 * The key to obtain the path to the VFEED data file. +273 * The additional configured zip file extensions, if available.274 */ -275publicstaticfinal String VFEED_DATA_FILE = "vfeed.data_file"; +275publicstaticfinal String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip"; 276/** -277 * The key to obtain the VFEED connection string. +277 * The key to obtain the path to the VFEED data file.278 */ -279publicstaticfinal String VFEED_CONNECTION_STRING = "vfeed.connection_string"; -280 -281/** -282 * The key to obtain the base download URL for the VFeed data file. -283 */ -284publicstaticfinal String VFEED_DOWNLOAD_URL = "vfeed.download_url"; +279publicstaticfinal String VFEED_DATA_FILE = "vfeed.data_file"; +280/** +281 * The key to obtain the VFEED connection string. +282 */ +283publicstaticfinal String VFEED_CONNECTION_STRING = "vfeed.connection_string"; +284285/** -286 * The key to obtain the download file name for the VFeed data. +286 * The key to obtain the base download URL for the VFeed data file.287 */ -288publicstaticfinal String VFEED_DOWNLOAD_FILE = "vfeed.download_file"; +288publicstaticfinal String VFEED_DOWNLOAD_URL = "vfeed.download_url"; 289/** -290 * The key to obtain the VFeed update status. +290 * The key to obtain the download file name for the VFeed data.291 */ -292publicstaticfinal String VFEED_UPDATE_STATUS = "vfeed.update_status"; -293 -294/** -295 * The HTTP request method for query last modified date. -296 */ -297publicstaticfinal String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp"; -298 } -299//</editor-fold> -300 -301/** -302 * The logger. -303 */ -304privatestaticfinal Logger LOGGER = LoggerFactory.getLogger(Settings.class); +292publicstaticfinal String VFEED_DOWNLOAD_FILE = "vfeed.download_file"; +293/** +294 * The key to obtain the VFeed update status. +295 */ +296publicstaticfinal String VFEED_UPDATE_STATUS = "vfeed.update_status"; +297 +298/** +299 * The HTTP request method for query last modified date. +300 */ +301publicstaticfinal String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp"; +302 } +303//</editor-fold> +304305/** -306 * The properties file location. +306 * The logger.307 */ -308privatestaticfinal String PROPERTIES_FILE = "dependencycheck.properties"; +308privatestaticfinal Logger LOGGER = LoggerFactory.getLogger(Settings.class); 309/** -310 * Thread local settings. +310 * The properties file location.311 */ -312privatestatic ThreadLocal<Settings> localSettings = new ThreadLocal<Settings>(); +312privatestaticfinal String PROPERTIES_FILE = "dependencycheck.properties"; 313/** -314 * The properties. +314 * Thread local settings.315 */ -316private Properties props = null; -317 -318/** -319 * Private constructor for the Settings class. This class loads the properties files. -320 * -321 * @param propertiesFilePath the path to the base properties file to load -322 */ -323privateSettings(String propertiesFilePath) { -324 InputStream in = null; -325 props = new Properties(); -326try { -327 in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath); -328 props.load(in); -329 } catch (IOException ex) { -330 LOGGER.error("Unable to load default settings."); -331 LOGGER.debug("", ex); -332 } finally { -333if (in != null) { -334try { -335 in.close(); -336 } catch (IOException ex) { -337 LOGGER.trace("", ex); -338 } -339 } -340 } -341 logProperties("Properties loaded", props); -342 } -343 -344/** -345 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must -346 * also call Settings.cleanup() to properly release resources. -347 */ -348publicstaticvoid initialize() { -349 localSettings.set(newSettings(PROPERTIES_FILE)); -350 } -351 -352/** -353 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must -354 * also call Settings.cleanup() to properly release resources. -355 * -356 * @param propertiesFilePath the path to the base properties file to load -357 */ -358publicstaticvoid initialize(String propertiesFilePath) { -359 localSettings.set(newSettings(propertiesFilePath)); -360 } -361 -362/** -363 * Cleans up resources to prevent memory leaks. -364 * -365 */ -366publicstaticvoid cleanup() { -367 cleanup(true); -368 } -369 -370/** -371 * Cleans up resources to prevent memory leaks. -372 * -373 * @param deleteTemporary flag indicating whether any temporary directories generated should be removed -374 */ -375publicstaticvoid cleanup(boolean deleteTemporary) { -376if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) { -377 FileUtils.delete(tempDirectory); -378if (tempDirectory.exists()) { -379try { -380 Thread.sleep(2000); -381 } catch (InterruptedException ex) { -382 LOGGER.trace("ignore", ex); -383 } -384 FileUtils.delete(tempDirectory); -385 } -386 } -387try { -388 localSettings.remove(); -389 } catch (Throwable ex) { -390 LOGGER.debug("Error cleaning up Settings", ex); -391 } -392 } -393 -394/** -395 * Gets the underlying instance of the Settings object. -396 * -397 * @return the Settings object -398 */ -399publicstaticSettings getInstance() { -400return localSettings.get(); -401 } -402 -403/** -404 * Sets the instance of the Settings object to use in this thread. -405 * -406 * @param instance the instance of the settings object to use in this thread -407 */ -408publicstaticvoid setInstance(Settings instance) { -409 localSettings.set(instance); -410 } -411 -412/** -413 * Logs the properties. This will not log any properties that contain 'password' in the key. -414 * -415 * @param header the header to print with the log message -416 * @param properties the properties to log -417 */ -418privatestaticvoid logProperties(String header, Properties properties) { -419if (LOGGER.isDebugEnabled()) { -420final StringWriter sw = new StringWriter(); -421 PrintWriter pw = null; -422try { -423 pw = new PrintWriter(sw); -424 pw.format("%s:%n%n", header); -425final Enumeration<?> e = properties.propertyNames(); -426while (e.hasMoreElements()) { -427final String key = (String) e.nextElement(); -428if (key.contains("password")) { -429 pw.format("%s='*****'%n", key); -430 } else { -431final String value = properties.getProperty(key); -432if (value != null) { -433 pw.format("%s='%s'%n", key, value); -434 } -435 } -436 } -437 pw.flush(); -438 LOGGER.debug(sw.toString()); -439 } finally { -440if (pw != null) { -441 pw.close(); -442 } -443 } -444 -445 } -446 } -447 -448/** -449 * Sets a property value. -450 * -451 * @param key the key for the property -452 * @param value the value for the property -453 */ -454publicstaticvoid setString(String key, String value) { -455 localSettings.get().props.setProperty(key, value); -456 LOGGER.debug("Setting: {}='{}'", key, value); -457 } -458 -459/** -460 * Sets a property value only if the value is not null. -461 * -462 * @param key the key for the property -463 * @param value the value for the property -464 */ -465publicstaticvoid setStringIfNotNull(String key, String value) { -466if (null != value) { -467 setString(key, value); -468 } -469 } -470 -471/** -472 * Sets a property value only if the value is not null and not empty. -473 * -474 * @param key the key for the property -475 * @param value the value for the property -476 */ -477publicstaticvoid setStringIfNotEmpty(String key, String value) { -478if (null != value && !value.isEmpty()) { -479 setString(key, value); -480 } -481 } -482 -483/** -484 * Sets a property value. -485 * -486 * @param key the key for the property -487 * @param value the value for the property -488 */ -489publicstaticvoid setBoolean(String key, boolean value) { -490 setString(key, Boolean.toString(value)); -491 } -492 -493/** -494 * Sets a property value only if the value is not null. -495 * -496 * @param key the key for the property -497 * @param value the value for the property -498 */ -499publicstaticvoid setBooleanIfNotNull(String key, Boolean value) { -500if (null != value) { -501 setBoolean(key, value); -502 } -503 } -504 -505/** -506 * Sets a property value. -507 * -508 * @param key the key for the property -509 * @param value the value for the property -510 */ -511publicstaticvoid setInt(String key, int value) { -512 localSettings.get().props.setProperty(key, String.valueOf(value)); -513 LOGGER.debug("Setting: {}='{}'", key, value); -514 } -515 -516/** -517 * Sets a property value only if the value is not null. -518 * -519 * @param key the key for the property -520 * @param value the value for the property -521 */ -522publicstaticvoid setIntIfNotNull(String key, Integer value) { -523if (null != value) { -524 setInt(key, value); -525 } -526 } -527 -528/** -529 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -530 * file.<br><br> -531 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. -532 * -533 * @param filePath the path to the properties file to merge. -534 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file -535 * @throws IOException is thrown when there is an exception loading/merging the properties -536 */ -537publicstaticvoid mergeProperties(File filePath) throws FileNotFoundException, IOException { -538 FileInputStream fis = null; -539try { -540 fis = new FileInputStream(filePath); -541 mergeProperties(fis); -542 } finally { -543if (fis != null) { -544try { -545 fis.close(); -546 } catch (IOException ex) { -547 LOGGER.trace("close error", ex); -548 } -549 } -550 } -551 } -552 -553/** -554 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -555 * file.<br><br> -556 * Note: even if using this method - system properties will be loaded before properties loaded from files. -557 * -558 * @param filePath the path to the properties file to merge. -559 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file -560 * @throws IOException is thrown when there is an exception loading/merging the properties -561 */ -562publicstaticvoid mergeProperties(String filePath) throws FileNotFoundException, IOException { -563 FileInputStream fis = null; -564try { -565 fis = new FileInputStream(filePath); -566 mergeProperties(fis); -567 } finally { -568if (fis != null) { -569try { -570 fis.close(); -571 } catch (IOException ex) { -572 LOGGER.trace("close error", ex); -573 } -574 } -575 } -576 } -577 -578/** -579 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -580 * file.<br><br> -581 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. -582 * -583 * @param stream an Input Stream pointing at a properties file to merge -584 * @throws IOException is thrown when there is an exception loading/merging the properties -585 */ -586publicstaticvoid mergeProperties(InputStream stream) throws IOException { -587 localSettings.get().props.load(stream); -588 logProperties("Properties updated via merge", localSettings.get().props); -589 } -590 -591/** -592 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via -593 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained -594 * configuration file. -595 * -596 * @param key the key to lookup within the properties file -597 * @return the property from the properties file converted to a File object -598 */ -599publicstatic File getFile(String key) { -600final String file = getString(key); -601if (file == null) { -602returnnull; -603 } -604returnnew File(file); -605 } -606 -607/** -608 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via -609 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained -610 * configuration file. -611 * -612 * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the -613 * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this -614 * class. +316privatestaticfinal ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>(); +317/** +318 * The properties. +319 */ +320private Properties props = null; +321 +322/** +323 * Private constructor for the Settings class. This class loads the properties files. +324 * +325 * @param propertiesFilePath the path to the base properties file to load +326 */ +327privateSettings(String propertiesFilePath) { +328 InputStream in = null; +329 props = new Properties(); +330try { +331 in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath); +332 props.load(in); +333 } catch (IOException ex) { +334 LOGGER.error("Unable to load default settings."); +335 LOGGER.debug("", ex); +336 } finally { +337if (in != null) { +338try { +339 in.close(); +340 } catch (IOException ex) { +341 LOGGER.trace("", ex); +342 } +343 } +344 } +345 logProperties("Properties loaded", props); +346 } +347 +348/** +349 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must +350 * also call Settings.cleanup() to properly release resources. +351 */ +352publicstaticvoid initialize() { +353 LOCAL_SETTINGS.set(newSettings(PROPERTIES_FILE)); +354 } +355 +356/** +357 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must +358 * also call Settings.cleanup() to properly release resources. +359 * +360 * @param propertiesFilePath the path to the base properties file to load +361 */ +362publicstaticvoid initialize(String propertiesFilePath) { +363 LOCAL_SETTINGS.set(newSettings(propertiesFilePath)); +364 } +365 +366/** +367 * Cleans up resources to prevent memory leaks. +368 * +369 */ +370publicstaticvoid cleanup() { +371 cleanup(true); +372 } +373 +374/** +375 * Cleans up resources to prevent memory leaks. +376 * +377 * @param deleteTemporary flag indicating whether any temporary directories generated should be removed +378 */ +379publicstaticvoid cleanup(boolean deleteTemporary) { +380if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) { +381 FileUtils.delete(tempDirectory); +382if (tempDirectory.exists()) { +383try { +384 Thread.sleep(2000); +385 } catch (InterruptedException ex) { +386 LOGGER.trace("ignore", ex); +387 } +388 FileUtils.delete(tempDirectory); +389 } +390 } +391try { +392 LOCAL_SETTINGS.remove(); +393 } catch (Throwable ex) { +394 LOGGER.debug("Error cleaning up Settings", ex); +395 } +396 } +397 +398/** +399 * Gets the underlying instance of the Settings object. +400 * +401 * @return the Settings object +402 */ +403publicstaticSettings getInstance() { +404return LOCAL_SETTINGS.get(); +405 } +406 +407/** +408 * Sets the instance of the Settings object to use in this thread. +409 * +410 * @param instance the instance of the settings object to use in this thread +411 */ +412publicstaticvoid setInstance(Settings instance) { +413 LOCAL_SETTINGS.set(instance); +414 } +415 +416/** +417 * Logs the properties. This will not log any properties that contain 'password' in the key. +418 * +419 * @param header the header to print with the log message +420 * @param properties the properties to log +421 */ +422privatestaticvoid logProperties(String header, Properties properties) { +423if (LOGGER.isDebugEnabled()) { +424final StringWriter sw = new StringWriter(); +425 PrintWriter pw = null; +426try { +427 pw = new PrintWriter(sw); +428 pw.format("%s:%n%n", header); +429final Enumeration<?> e = properties.propertyNames(); +430while (e.hasMoreElements()) { +431final String key = (String) e.nextElement(); +432if (key.contains("password")) { +433 pw.format("%s='*****'%n", key); +434 } else { +435final String value = properties.getProperty(key); +436if (value != null) { +437 pw.format("%s='%s'%n", key, value); +438 } +439 } +440 } +441 pw.flush(); +442 LOGGER.debug(sw.toString()); +443 } finally { +444if (pw != null) { +445 pw.close(); +446 } +447 } +448 +449 } +450 } +451 +452/** +453 * Sets a property value. +454 * +455 * @param key the key for the property +456 * @param value the value for the property +457 */ +458publicstaticvoid setString(String key, String value) { +459 LOCAL_SETTINGS.get().props.setProperty(key, value); +460 LOGGER.debug("Setting: {}='{}'", key, value); +461 } +462 +463/** +464 * Sets a property value only if the value is not null. +465 * +466 * @param key the key for the property +467 * @param value the value for the property +468 */ +469publicstaticvoid setStringIfNotNull(String key, String value) { +470if (null != value) { +471 setString(key, value); +472 } +473 } +474 +475/** +476 * Sets a property value only if the value is not null and not empty. +477 * +478 * @param key the key for the property +479 * @param value the value for the property +480 */ +481publicstaticvoid setStringIfNotEmpty(String key, String value) { +482if (null != value && !value.isEmpty()) { +483 setString(key, value); +484 } +485 } +486 +487/** +488 * Sets a property value. +489 * +490 * @param key the key for the property +491 * @param value the value for the property +492 */ +493publicstaticvoid setBoolean(String key, boolean value) { +494 setString(key, Boolean.toString(value)); +495 } +496 +497/** +498 * Sets a property value only if the value is not null. +499 * +500 * @param key the key for the property +501 * @param value the value for the property +502 */ +503publicstaticvoid setBooleanIfNotNull(String key, Boolean value) { +504if (null != value) { +505 setBoolean(key, value); +506 } +507 } +508 +509/** +510 * Sets a property value. +511 * +512 * @param key the key for the property +513 * @param value the value for the property +514 */ +515publicstaticvoid setInt(String key, int value) { +516 LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value)); +517 LOGGER.debug("Setting: {}='{}'", key, value); +518 } +519 +520/** +521 * Sets a property value only if the value is not null. +522 * +523 * @param key the key for the property +524 * @param value the value for the property +525 */ +526publicstaticvoid setIntIfNotNull(String key, Integer value) { +527if (null != value) { +528 setInt(key, value); +529 } +530 } +531 +532/** +533 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties +534 * file.<br><br> +535 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. +536 * +537 * @param filePath the path to the properties file to merge. +538 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file +539 * @throws IOException is thrown when there is an exception loading/merging the properties +540 */ +541publicstaticvoid mergeProperties(File filePath) throws FileNotFoundException, IOException { +542 FileInputStream fis = null; +543try { +544 fis = new FileInputStream(filePath); +545 mergeProperties(fis); +546 } finally { +547if (fis != null) { +548try { +549 fis.close(); +550 } catch (IOException ex) { +551 LOGGER.trace("close error", ex); +552 } +553 } +554 } +555 } +556 +557/** +558 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties +559 * file.<br><br> +560 * Note: even if using this method - system properties will be loaded before properties loaded from files. +561 * +562 * @param filePath the path to the properties file to merge. +563 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file +564 * @throws IOException is thrown when there is an exception loading/merging the properties +565 */ +566publicstaticvoid mergeProperties(String filePath) throws FileNotFoundException, IOException { +567 FileInputStream fis = null; +568try { +569 fis = new FileInputStream(filePath); +570 mergeProperties(fis); +571 } finally { +572if (fis != null) { +573try { +574 fis.close(); +575 } catch (IOException ex) { +576 LOGGER.trace("close error", ex); +577 } +578 } +579 } +580 } +581 +582/** +583 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties +584 * file.<br><br> +585 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. +586 * +587 * @param stream an Input Stream pointing at a properties file to merge +588 * @throws IOException is thrown when there is an exception loading/merging the properties +589 */ +590publicstaticvoid mergeProperties(InputStream stream) throws IOException { +591 LOCAL_SETTINGS.get().props.load(stream); +592 logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props); +593 } +594 +595/** +596 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via +597 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained +598 * configuration file. +599 * +600 * @param key the key to lookup within the properties file +601 * @return the property from the properties file converted to a File object +602 */ +603publicstatic File getFile(String key) { +604final String file = getString(key); +605if (file == null) { +606returnnull; +607 } +608returnnew File(file); +609 } +610 +611/** +612 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via +613 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained +614 * configuration file.615 * -616 * @param key the key to lookup within the properties file -617 * @return the property from the properties file converted to a File object -618 */ -619protectedstatic File getDataFile(String key) { -620final String file = getString(key); -621 LOGGER.debug("Settings.getDataFile() - file: '{}'", file); -622if (file == null) { -623returnnull; -624 } -625if (file.startsWith("[JAR]")) { -626 LOGGER.debug("Settings.getDataFile() - transforming filename"); -627final File jarPath = getJarPath(); -628 LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString()); -629final File retVal = new File(jarPath, file.substring(6)); -630 LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString()); -631return retVal; -632 } -633returnnew File(file); -634 } -635 -636/** -637 * Attempts to retrieve the folder containing the Jar file containing the Settings class. -638 * -639 * @return a File object -640 */ -641privatestatic File getJarPath() { -642final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath(); -643 String decodedPath = "."; -644try { -645 decodedPath = URLDecoder.decode(jarPath, "UTF-8"); -646 } catch (UnsupportedEncodingException ex) { -647 LOGGER.trace("", ex); -648 } -649 -650final File path = new File(decodedPath); -651if (path.getName().toLowerCase().endsWith(".jar")) { -652return path.getParentFile(); -653 } else { -654returnnew File("."); -655 } -656 } -657 -658/** -659 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value -660 * argument - this method will return the value from the system properties before the values in the contained configuration -661 * file. -662 * -663 * @param key the key to lookup within the properties file -664 * @param defaultValue the default value for the requested property -665 * @return the property from the properties file -666 */ -667publicstatic String getString(String key, String defaultValue) { -668final String str = System.getProperty(key, localSettings.get().props.getProperty(key, defaultValue)); -669return str; -670 } -671 -672/** -673 * A reference to the temporary directory; used incase it needs to be deleted during cleanup. -674 */ -675privatestatic File tempDirectory = null; -676 -677/** -678 * Returns the temporary directory. -679 * -680 * @return the temporary directory -681 * @throws java.io.IOException thrown if the temporary directory does not exist and cannot be created -682 */ -683publicstatic File getTempDirectory() throws IOException { -684final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp"); -685if (!tmpDir.exists() && !tmpDir.mkdirs()) { -686final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath()); -687thrownew IOException(msg); -688 } -689 tempDirectory = tmpDir; -690return tmpDir; -691 } -692 -693/** -694 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value -695 * argument - this method will return the value from the system properties before the values in the contained configuration -696 * file. -697 * -698 * @param key the key to lookup within the properties file -699 * @return the property from the properties file -700 */ -701publicstatic String getString(String key) { -702return System.getProperty(key, localSettings.get().props.getProperty(key)); -703 } -704 -705/** -706 * Removes a property from the local properties collection. This is mainly used in test cases. -707 * -708 * @param key the property key to remove -709 */ -710publicstaticvoid removeProperty(String key) { -711 localSettings.get().props.remove(key); -712 } -713 -714/** -715 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the -716 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -717 * configuration file. -718 * -719 * @param key the key to lookup within the properties file -720 * @return the property from the properties file -721 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -722 */ -723publicstaticint getInt(String key) throws InvalidSettingException { -724try { -725return Integer.parseInt(Settings.getString(key)); -726 } catch (NumberFormatException ex) { -727thrownewInvalidSettingException("Could not convert property '" + key + "' to an int.", ex); -728 } -729 } -730 -731/** -732 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the -733 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -734 * configuration file. -735 * -736 * @param key the key to lookup within the properties file -737 * @param defaultValue the default value to return -738 * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to -739 * an integer -740 */ -741publicstaticint getInt(String key, int defaultValue) { -742int value; -743try { -744 value = Integer.parseInt(Settings.getString(key)); -745 } catch (NumberFormatException ex) { -746if (!Settings.getString(key, "").isEmpty()) { -747 LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue); -748 } -749 value = defaultValue; -750 } -751return value; -752 } -753 -754/** -755 * Returns a long value from the properties file. If the value was specified as a system property or passed in via the -756 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -757 * configuration file. -758 * -759 * @param key the key to lookup within the properties file -760 * @return the property from the properties file -761 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -762 */ -763publicstaticlong getLong(String key) throws InvalidSettingException { -764try { -765return Long.parseLong(Settings.getString(key)); -766 } catch (NumberFormatException ex) { -767thrownewInvalidSettingException("Could not convert property '" + key + "' to a long.", ex); -768 } -769 } -770 -771/** -772 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the -773 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the -774 * contained configuration file. -775 * -776 * @param key the key to lookup within the properties file -777 * @return the property from the properties file -778 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -779 */ -780publicstaticboolean getBoolean(String key) throws InvalidSettingException { -781return Boolean.parseBoolean(Settings.getString(key)); -782 } -783 -784/** -785 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the -786 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the -787 * contained configuration file. -788 * -789 * @param key the key to lookup within the properties file -790 * @param defaultValue the default value to return if the setting does not exist -791 * @return the property from the properties file -792 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -793 */ -794publicstaticboolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException { -795return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue))); -796 } -797 -798/** -799 * Returns a connection string from the configured properties. If the connection string contains a %s, this method will -800 * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not -801 * exists it will be created. -802 * -803 * @param connectionStringKey the property file key for the connection string -804 * @param dbFileNameKey the settings key for the db filename -805 * @return the connection string -806 * @throws IOException thrown the data directory cannot be created -807 * @throws InvalidSettingException thrown if there is an invalid setting -808 */ -809publicstatic String getConnectionString(String connectionStringKey, String dbFileNameKey) -810throws IOException, InvalidSettingException { -811final String connStr = Settings.getString(connectionStringKey); -812if (connStr == null) { -813final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey); -814thrownewInvalidSettingException(msg); -815 } -816if (connStr.contains("%s")) { -817final File directory = getDataDirectory(); -818 String fileName = null; -819if (dbFileNameKey != null) { -820 fileName = Settings.getString(dbFileNameKey); -821 } -822if (fileName == null) { -823final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.", -824 dbFileNameKey); -825thrownewInvalidSettingException(msg); -826 } -827if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) { -828 fileName = fileName.substring(0, fileName.length() - 6); -829 } -830// yes, for H2 this path won't actually exists - but this is sufficient to get the value needed -831final File dbFile = new File(directory, fileName); -832final String cString = String.format(connStr, dbFile.getCanonicalPath()); -833 LOGGER.debug("Connection String: '{}'", cString); -834return cString; -835 } -836return connStr; -837 } -838 -839/** -840 * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the -841 * embedded H2 database. This is public solely for some unit tests; otherwise this should be private. -842 * -843 * @return the data directory to store data files -844 * @throws IOException is thrown if an IOException occurs of course... -845 */ -846publicstatic File getDataDirectory() throws IOException { -847final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY); -848if (path.exists() || path.mkdirs()) { -849return path; -850 } -851thrownew IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath())); -852 } -853 } +616 * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the +617 * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this +618 * class. +619 * +620 * @param key the key to lookup within the properties file +621 * @return the property from the properties file converted to a File object +622 */ +623protectedstatic File getDataFile(String key) { +624final String file = getString(key); +625 LOGGER.debug("Settings.getDataFile() - file: '{}'", file); +626if (file == null) { +627returnnull; +628 } +629if (file.startsWith("[JAR]")) { +630 LOGGER.debug("Settings.getDataFile() - transforming filename"); +631final File jarPath = getJarPath(); +632 LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString()); +633final File retVal = new File(jarPath, file.substring(6)); +634 LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString()); +635return retVal; +636 } +637returnnew File(file); +638 } +639 +640/** +641 * Attempts to retrieve the folder containing the Jar file containing the Settings class. +642 * +643 * @return a File object +644 */ +645privatestatic File getJarPath() { +646final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath(); +647 String decodedPath = "."; +648try { +649 decodedPath = URLDecoder.decode(jarPath, "UTF-8"); +650 } catch (UnsupportedEncodingException ex) { +651 LOGGER.trace("", ex); +652 } +653 +654final File path = new File(decodedPath); +655if (path.getName().toLowerCase().endsWith(".jar")) { +656return path.getParentFile(); +657 } else { +658returnnew File("."); +659 } +660 } +661 +662/** +663 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value +664 * argument - this method will return the value from the system properties before the values in the contained configuration +665 * file. +666 * +667 * @param key the key to lookup within the properties file +668 * @param defaultValue the default value for the requested property +669 * @return the property from the properties file +670 */ +671publicstatic String getString(String key, String defaultValue) { +672final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue)); +673return str; +674 } +675 +676/** +677 * A reference to the temporary directory; used incase it needs to be deleted during cleanup. +678 */ +679privatestatic File tempDirectory = null; +680 +681/** +682 * Returns the temporary directory. +683 * +684 * @return the temporary directory +685 * @throws java.io.IOException thrown if the temporary directory does not exist and cannot be created +686 */ +687publicstatic File getTempDirectory() throws IOException { +688final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp"); +689if (!tmpDir.exists() && !tmpDir.mkdirs()) { +690final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath()); +691thrownew IOException(msg); +692 } +693 tempDirectory = tmpDir; +694return tmpDir; +695 } +696 +697/** +698 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value +699 * argument - this method will return the value from the system properties before the values in the contained configuration +700 * file. +701 * +702 * @param key the key to lookup within the properties file +703 * @return the property from the properties file +704 */ +705publicstatic String getString(String key) { +706return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key)); +707 } +708 +709/** +710 * Removes a property from the local properties collection. This is mainly used in test cases. +711 * +712 * @param key the property key to remove +713 */ +714publicstaticvoid removeProperty(String key) { +715 LOCAL_SETTINGS.get().props.remove(key); +716 } +717 +718/** +719 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the +720 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained +721 * configuration file. +722 * +723 * @param key the key to lookup within the properties file +724 * @return the property from the properties file +725 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +726 */ +727publicstaticint getInt(String key) throws InvalidSettingException { +728try { +729return Integer.parseInt(Settings.getString(key)); +730 } catch (NumberFormatException ex) { +731thrownewInvalidSettingException("Could not convert property '" + key + "' to an int.", ex); +732 } +733 } +734 +735/** +736 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the +737 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained +738 * configuration file. +739 * +740 * @param key the key to lookup within the properties file +741 * @param defaultValue the default value to return +742 * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to +743 * an integer +744 */ +745publicstaticint getInt(String key, int defaultValue) { +746int value; +747try { +748 value = Integer.parseInt(Settings.getString(key)); +749 } catch (NumberFormatException ex) { +750if (!Settings.getString(key, "").isEmpty()) { +751 LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue); +752 } +753 value = defaultValue; +754 } +755return value; +756 } +757 +758/** +759 * Returns a long value from the properties file. If the value was specified as a system property or passed in via the +760 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained +761 * configuration file. +762 * +763 * @param key the key to lookup within the properties file +764 * @return the property from the properties file +765 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +766 */ +767publicstaticlong getLong(String key) throws InvalidSettingException { +768try { +769return Long.parseLong(Settings.getString(key)); +770 } catch (NumberFormatException ex) { +771thrownewInvalidSettingException("Could not convert property '" + key + "' to a long.", ex); +772 } +773 } +774 +775/** +776 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the +777 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the +778 * contained configuration file. +779 * +780 * @param key the key to lookup within the properties file +781 * @return the property from the properties file +782 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +783 */ +784publicstaticboolean getBoolean(String key) throws InvalidSettingException { +785return Boolean.parseBoolean(Settings.getString(key)); +786 } +787 +788/** +789 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the +790 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the +791 * contained configuration file. +792 * +793 * @param key the key to lookup within the properties file +794 * @param defaultValue the default value to return if the setting does not exist +795 * @return the property from the properties file +796 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +797 */ +798publicstaticboolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException { +799return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue))); +800 } +801 +802/** +803 * Returns a connection string from the configured properties. If the connection string contains a %s, this method will +804 * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not +805 * exists it will be created. +806 * +807 * @param connectionStringKey the property file key for the connection string +808 * @param dbFileNameKey the settings key for the db filename +809 * @return the connection string +810 * @throws IOException thrown the data directory cannot be created +811 * @throws InvalidSettingException thrown if there is an invalid setting +812 */ +813publicstatic String getConnectionString(String connectionStringKey, String dbFileNameKey) +814throws IOException, InvalidSettingException { +815final String connStr = Settings.getString(connectionStringKey); +816if (connStr == null) { +817final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey); +818thrownewInvalidSettingException(msg); +819 } +820if (connStr.contains("%s")) { +821final File directory = getDataDirectory(); +822 String fileName = null; +823if (dbFileNameKey != null) { +824 fileName = Settings.getString(dbFileNameKey); +825 } +826if (fileName == null) { +827final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.", +828 dbFileNameKey); +829thrownewInvalidSettingException(msg); +830 } +831if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) { +832 fileName = fileName.substring(0, fileName.length() - 6); +833 } +834// yes, for H2 this path won't actually exists - but this is sufficient to get the value needed +835final File dbFile = new File(directory, fileName); +836final String cString = String.format(connStr, dbFile.getCanonicalPath()); +837 LOGGER.debug("Connection String: '{}'", cString); +838return cString; +839 } +840return connStr; +841 } +842 +843/** +844 * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the +845 * embedded H2 database. This is public solely for some unit tests; otherwise this should be private. +846 * +847 * @return the data directory to store data files +848 * @throws IOException is thrown if an IOException occurs of course... +849 */ +850publicstatic File getDataDirectory() throws IOException { +851final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY); +852if (path.exists() || path.mkdirs()) { +853return path; +854 } +855thrownew IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath())); +856 } +857 }
      diff --git a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-frame.html b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-frame.html index ef86dd68f..23da808ad 100644 --- a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-frame.html +++ b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Utils 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-summary.html index 456cf6554..d6d764b58 100644 --- a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Utils 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-utils/xref/overview-frame.html b/dependency-check-utils/xref/overview-frame.html index 7f5f75f75..fa6fa0f94 100644 --- a/dependency-check-utils/xref/overview-frame.html +++ b/dependency-check-utils/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.3.6 Reference + Dependency-Check Utils 1.4.0 Reference diff --git a/dependency-check-utils/xref/overview-summary.html b/dependency-check-utils/xref/overview-summary.html index 9d7f20b53..b26443869 100644 --- a/dependency-check-utils/xref/overview-summary.html +++ b/dependency-check-utils/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.3.6 Reference + Dependency-Check Utils 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Utils 1.3.6 Reference

      +

      Dependency-Check Utils 1.4.0 Reference

      diff --git a/dependency-updates-report.html b/dependency-updates-report.html index 5765ad958..3c545cfd1 100644 --- a/dependency-updates-report.html +++ b/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check – Dependency Updates Report @@ -59,9 +59,9 @@
    89. Dependency Updates Report
    90. -
    91. | Last Published: 2016-04-09
    92. +
    93. | Last Published: 2016-06-16
    94. - Version: 1.3.6 + Version: 1.4.0
    95. @@ -182,9 +182,6 @@ developed using - - - built on cloudbees @@ -200,7 +197,7 @@ - + @@ -208,11 +205,11 @@ - + - + @@ -320,7 +317,7 @@ - + @@ -344,7 +341,7 @@ - + @@ -356,7 +353,7 @@ - + @@ -437,39 +434,39 @@ - + - + - + - + - + - + - + - + - + @@ -545,7 +542,7 @@ - + @@ -554,18 +551,18 @@ - + - + - + - + @@ -720,7 +717,7 @@ -
      # of dependencies using the latest version available21
      22
      # of dependencies where the next version available is smaller than an incremental version update
      # of dependencies where the next version available is an incremental version update3
      1
      # of dependencies where the next version available is a minor version update6
      7
      # of dependencies where the next version available is a major version update commons-io commons-io2.42.5 jar org.apache.ant ant1.9.61.9.7 jar org.apache.ant ant-testutil1.9.61.9.7 jar4.8.0 5.0.0
      org.apache.maven maven-core3.3.33.3.9 jar 3.3.9
      org.apache.maven maven-plugin-api3.3.33.3.9 jar 3.3.9
      org.apache.maven maven-settings3.3.33.3.9 jar 3.3.9
      org.jmockit jmockit 1.22jar 1.23
      org.jsoup jsoup1.8.31.9.1 jar 1.9.2
      jar
      Newer versions1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191 Latest Minor
      +1.4.177 Next Minor
      1.4.178
      1.4.179
      1.4.180
      1.4.181
      1.4.182
      1.4.183
      1.4.184
      1.4.185
      1.4.186
      1.4.187
      1.4.188
      1.4.189
      1.4.190
      1.4.191
      1.4.192 Latest Minor

      com.sun.mail:mailapi

      @@ -810,7 +807,7 @@ - + @@ -858,7 +855,7 @@ - + @@ -882,7 +879,7 @@ - + @@ -969,7 +966,7 @@ -
      commons-io
      Current Version2.4
      2.5
      Scope
      ant
      Current Version1.9.6
      1.9.7
      Scope
      ant-testutil
      Current Version1.9.6
      1.9.7
      Scope
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-core

      @@ -996,7 +993,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1023,7 +1020,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1050,13 +1047,13 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      6.0.0 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major

      org.apache.maven:maven-core

      - + @@ -1065,7 +1062,7 @@ - + @@ -1074,16 +1071,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-core
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-plugin-api

      - + @@ -1092,7 +1086,7 @@ - + @@ -1101,16 +1095,13 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-plugin-api
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven:maven-settings

      - + @@ -1119,7 +1110,7 @@ - + @@ -1128,10 +1119,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.apache.maven
      maven-settings
      Current Version3.3.3
      3.3.9
      Scope
      Typejar
      Newer versions3.3.9 Next Incremental
      +jar

      org.apache.maven.plugin-testing:maven-plugin-testing-harness

      @@ -1281,7 +1269,7 @@
      - + @@ -1299,13 +1287,16 @@ -
      Status No newer versions available.
       There is at least one newer minor version available. Minor updates are sometimes passive.
      Group Id org.jmockit
      Typejar
      +jar + +Newer versions +1.23 Next Minor
      1.24 Latest Minor

      org.jsoup:jsoup

      - + @@ -1314,7 +1305,7 @@ - + @@ -1323,7 +1314,10 @@ -
      Status No newer versions available.
       There is at least one newer incremental version available. Incremental updates are typically passive.
      Group Id org.jsoup
      jsoup
      Current Version1.8.3
      1.9.1
      Scope
      Typejar
      +jar + +Newer versions +1.9.2 Next Incremental

      org.slf4j:slf4j-api

      diff --git a/general/internals.html b/general/internals.html index ee3e2d736..b2dd55335 100644 --- a/general/internals.html +++ b/general/internals.html @@ -1,13 +1,13 @@ - + dependency-check – How does dependency-check work? @@ -59,9 +59,9 @@
    96. How does dependency-check work?
    97. -
    98. | Last Published: 2016-04-09
    99. +
    100. | Last Published: 2016-06-16
    101. - Version: 1.3.6 + Version: 1.4.0
    102. @@ -203,9 +203,6 @@ developed using - - - built on cloudbees diff --git a/general/scan_iso.html b/general/scan_iso.html index 4f6dcf8ed..0133bca1c 100644 --- a/general/scan_iso.html +++ b/general/scan_iso.html @@ -1,13 +1,13 @@ - + dependency-check – How to Mount ISO Files for Scanning @@ -59,9 +59,9 @@
    103. How to Mount ISO Files for Scanning
    104. -
    105. | Last Published: 2016-04-09
    106. +
    107. | Last Published: 2016-06-16
    108. - Version: 1.3.6 + Version: 1.4.0
    109. @@ -203,9 +203,6 @@ developed using - - - built on cloudbees diff --git a/general/suppression.html b/general/suppression.html index 42559d619..9ab3a7e38 100644 --- a/general/suppression.html +++ b/general/suppression.html @@ -1,13 +1,13 @@ - + dependency-check – Suppressing False Positives @@ -59,9 +59,9 @@
    110. Suppressing False Positives
    111. -
    112. | Last Published: 2016-04-09
    113. +
    114. | Last Published: 2016-06-16
    115. - Version: 1.3.6 + Version: 1.4.0
    116. @@ -203,9 +203,6 @@ developed using - - - built on cloudbees @@ -220,7 +217,7 @@
      <?xml version="1.0" encoding="UTF-8"?>
      -<suppressions xmlns="https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression">
      +<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">
          <suppress>
             <notes><![CDATA[
             file name: some.jar
      @@ -235,10 +232,7 @@
       
       
      <?xml version="1.0" encoding="UTF-8"?>
      -<suppressions
      -    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
      -    xmlns='https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression'
      -    xsi:schemaLocation='https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression suppression.xsd'>
      +<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">
           <suppress>
               <notes><![CDATA[
               This suppresses cpe:/a:csv:csv:1.0 for some.jar in the "c:\path\to" directory.
      diff --git a/general/thereport.html b/general/thereport.html
      index 8fba49f83..2f35a96ea 100644
      --- a/general/thereport.html
      +++ b/general/thereport.html
      @@ -1,13 +1,13 @@
       
       
       
         
           
           
      -    
      +    
           
           dependency-check – How To Read The Reports
           
      @@ -59,9 +59,9 @@
               
    117. How To Read The Reports
    118. -
    119. | Last Published: 2016-04-09
    120. +
    121. | Last Published: 2016-06-16
    122. - Version: 1.3.6 + Version: 1.4.0
    123. @@ -203,9 +203,6 @@ developed using - - - built on cloudbees
      diff --git a/index.html b/index.html index 066a94f94..fc1272fe9 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,13 @@ - + dependency-check – About @@ -59,9 +59,9 @@
    124. About
    125. -
    126. | Last Published: 2016-04-09
    127. +
    128. | Last Published: 2016-06-16
    129. - Version: 1.3.6 + Version: 1.4.0
    130. @@ -203,9 +203,6 @@ developed using - - - built on cloudbees
      @@ -215,7 +212,7 @@

      About

      -

      OWASP dependency-check is an open source solution the OWASP Top 10 2013 entry: A9 - Using Components with Known Vulnerabilities. Dependency-check can currently be used to scan Java, .NET, Python, Ruby (gemspec), PHP (composer), and Node.js applications (and their dependent libraries) to identify known vulnerable components. In addition, Dependency-check can be used to scan some source code, including OpenSSL source code and projects that use Autoconf or CMake.

      +

      OWASP dependency-check is an open source solution the OWASP Top 10 2013 entry: A9 - Using Components with Known Vulnerabilities. Dependency-check can currently be used to scan Java and .NET applications to identify the use of known vulnerable components. Experimental analyzers for Python, Ruby, PHP (composer), and Node.js applications; these are experimental due to the possible false positive and false negative rates. To use the experimental analyzers they must be specifically enabled via the appropriate experimental configuration. In addition, dependency-check has experimental analyzers that can be used to scan some C/C++ source code, including OpenSSL source code and projects that use Autoconf or CMake.

      The problem with using known vulnerable components was covered in a paper by Jeff Williams and Arshan Dabirsiaghi titled, “The Unfortunate Reality of Insecure Libraries” (registration required). The gist of the paper is that we as a development community include third party libraries in our applications that contain well known published vulnerabilities (such as those at the National Vulnerability Database).

      More information about dependency-check can be found here:

      @@ -240,6 +237,14 @@
    131. Gradle Plugin
    132. Jenkins Plugin
    133. + +

      For help with dependency-check the following resource can be used:

      + +
      diff --git a/integration.html b/integration.html index 04fb6e7a3..2d6789635 100644 --- a/integration.html +++ b/integration.html @@ -1,13 +1,13 @@ - + dependency-check – CI Management @@ -59,9 +59,9 @@
    134. CI Management
    135. -
    136. | Last Published: 2016-04-09
    137. +
    138. | Last Published: 2016-06-16
    139. - Version: 1.3.6 + Version: 1.4.0
    140. @@ -196,9 +196,6 @@ developed using - - - built on cloudbees @@ -209,11 +206,11 @@

      Overview

      -

      This project uses Continuous Integration System.

      +

      This project uses Travis CI.

      Access

      The following is a link to the continuous integration system used by the project:

      -
      +

      Notifiers

      No notifiers are defined. Please check back at a later date.

      diff --git a/issue-tracking.html b/issue-tracking.html index c1efdcdf9..1bf5d23d6 100644 --- a/issue-tracking.html +++ b/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check – Issue Management @@ -59,9 +59,9 @@
    141. Issue Management
    142. -
    143. | Last Published: 2016-04-09
    144. +
    145. | Last Published: 2016-06-16
    146. - Version: 1.3.6 + Version: 1.4.0
    147. @@ -196,9 +196,6 @@ developed using - - - built on cloudbees diff --git a/license.html b/license.html index 889b02813..03d77a0eb 100644 --- a/license.html +++ b/license.html @@ -1,13 +1,13 @@ - + dependency-check – Project Licenses @@ -59,9 +59,9 @@
    148. Project Licenses
    149. -
    150. | Last Published: 2016-04-09
    151. +
    152. | Last Published: 2016-06-16
    153. - Version: 1.3.6 + Version: 1.4.0
    154. @@ -196,9 +196,6 @@ developed using - - - built on cloudbees diff --git a/mail-lists.html b/mail-lists.html index f3db6bdfb..087aba6d4 100644 --- a/mail-lists.html +++ b/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check – Project Mailing Lists @@ -59,9 +59,9 @@
    155. Project Mailing Lists
    156. -
    157. | Last Published: 2016-04-09
    158. +
    159. | Last Published: 2016-06-16
    160. - Version: 1.3.6 + Version: 1.4.0
    161. @@ -196,9 +196,6 @@ developed using - - - built on cloudbees diff --git a/modules.html b/modules.html index ee221043e..903a7daa8 100644 --- a/modules.html +++ b/modules.html @@ -1,13 +1,13 @@ - + dependency-check – Modules @@ -59,9 +59,9 @@
    162. Modules
    163. -
    164. | Last Published: 2016-04-09
    165. +
    166. | Last Published: 2016-06-16
    167. - Version: 1.3.6 + Version: 1.4.0
    168. @@ -245,9 +245,6 @@ developed using - - - built on cloudbees diff --git a/plugin-updates-report.html b/plugin-updates-report.html index 223680e3d..1a65d6c6a 100644 --- a/plugin-updates-report.html +++ b/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check – Plugin Updates Report @@ -59,9 +59,9 @@
    169. Plugin Updates Report
    170. -
    171. | Last Published: 2016-04-09
    172. +
    173. | Last Published: 2016-06-16
    174. - Version: 1.3.6 + Version: 1.4.0
    175. @@ -182,9 +182,6 @@ developed using - - - built on cloudbees @@ -200,7 +197,7 @@ - + @@ -216,7 +213,7 @@ - + @@ -338,7 +335,7 @@ - + @@ -368,7 +365,7 @@ - + @@ -378,21 +375,21 @@ - + - + - - + + @@ -604,7 +601,7 @@ -
      # of plugins using the latest version available19
      18
      # of plugins where the next version available is smaller than an incremental version update
      # of plugins where the next version available is a major version update0
      1
      # of plugins where a dependencies section containes a dependency with an updated version org.apache.maven.plugins maven-jar-plugin2.63.0.0 org.apache.maven.plugins maven-resources-plugin2.73.0.0 org.apache.maven.plugins maven-site-plugin3.53.5.1
      org.apache.maven.plugins maven-source-plugin2.42.4 3.0.0
      maven-jar-plugin
      Current Version2.6
      +3.0.0

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -649,7 +646,7 @@ -
      maven-resources-plugin
      Current Version2.7
      +3.0.0

      Plugin org.apache.maven.plugins:maven-site-plugin

      @@ -664,13 +661,13 @@ -
      maven-site-plugin
      Current Version3.5
      +3.5.1

      Plugin org.apache.maven.plugins:maven-source-plugin

      - + @@ -679,7 +676,10 @@ -
      Status No newer versions available.
       There is at least one newer major version available. Major updates are rarely passive.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      +2.4 + +Newer versions +3.0.0 Next Major

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/project-info.html b/project-info.html index 49ef250ec..4b92e9eaf 100644 --- a/project-info.html +++ b/project-info.html @@ -1,13 +1,13 @@ - + dependency-check – Project Information @@ -59,9 +59,9 @@
    176. Project Information
    177. -
    178. | Last Published: 2016-04-09
    179. +
    180. | Last Published: 2016-06-16
    181. - Version: 1.3.6 + Version: 1.4.0
    182. @@ -196,9 +196,6 @@ developed using - - - built on cloudbees diff --git a/project-reports.html b/project-reports.html index 099241762..51194aaa7 100644 --- a/project-reports.html +++ b/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check – Generated Reports @@ -59,9 +59,9 @@
    183. Generated Reports
    184. -
    185. | Last Published: 2016-04-09
    186. +
    187. | Last Published: 2016-06-16
    188. - Version: 1.3.6 + Version: 1.4.0
    189. @@ -182,9 +182,6 @@ developed using - - - built on cloudbees diff --git a/project-summary.html b/project-summary.html index dd043ab86..8858ca28e 100644 --- a/project-summary.html +++ b/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check – Project Summary @@ -59,9 +59,9 @@
    190. Project Summary
    191. -
    192. | Last Published: 2016-04-09
    193. +
    194. | Last Published: 2016-06-16
    195. - Version: 1.3.6 + Version: 1.4.0
    196. @@ -196,9 +196,6 @@ developed using - - - built on cloudbees @@ -250,7 +247,7 @@ - +
      dependency-check-parent
      Version1.3.6
      1.4.0
      Type pom
      diff --git a/related.html b/related.html index d3464377a..a5afed529 100644 --- a/related.html +++ b/related.html @@ -1,13 +1,13 @@ - + dependency-check – Related Work @@ -59,9 +59,9 @@
    197. Related Work
    198. -
    199. | Last Published: 2016-04-09
    200. +
    201. | Last Published: 2016-06-16
    202. - Version: 1.3.6 + Version: 1.4.0
    203. @@ -203,9 +203,6 @@ developed using - - - built on cloudbees diff --git a/source-repository.html b/source-repository.html index b7c1d32d6..142f295e5 100644 --- a/source-repository.html +++ b/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check – Source Code Management @@ -59,9 +59,9 @@
    204. Source Code Management
    205. -
    206. | Last Published: 2016-04-09
    207. +
    208. | Last Published: 2016-06-16
    209. - Version: 1.3.6 + Version: 1.4.0
    210. @@ -196,9 +196,6 @@ developed using - - - built on cloudbees diff --git a/surefire-report.html b/surefire-report.html index e39e5a34c..3fcaab6e6 100644 --- a/surefire-report.html +++ b/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check – Surefire Report @@ -59,9 +59,9 @@
    211. Surefire Report
    212. -
    213. | Last Published: 2016-04-09
    214. +
    215. | Last Published: 2016-06-16
    216. - Version: 1.3.6 + Version: 1.4.0
    217. @@ -182,9 +182,6 @@ developed using - - - built on cloudbees diff --git a/team-list.html b/team-list.html index b6ffdb08d..f56ab10b8 100644 --- a/team-list.html +++ b/team-list.html @@ -1,13 +1,13 @@ - + dependency-check – Project Team @@ -59,9 +59,9 @@
    218. Project Team
    219. -
    220. | Last Published: 2016-04-09
    221. +
    222. | Last Published: 2016-06-16
    223. - Version: 1.3.6 + Version: 1.4.0
    224. @@ -196,9 +196,6 @@ developed using - - - built on cloudbees diff --git a/xref-test/allclasses-frame.html b/xref-test/allclasses-frame.html index cda9579d0..7d0078084 100644 --- a/xref-test/allclasses-frame.html +++ b/xref-test/allclasses-frame.html @@ -211,6 +211,9 @@
    225. RubyBundleAuditAnalyzerTest +
    226. +
    227. + RubyBundlerAnalyzerTest
    228. RubyGemspecAnalyzerTest @@ -241,6 +244,9 @@
    229. VulnerabilitySuppressionAnalyzerIntegrationTest +
    230. +
    231. + VulnerabilityTest
    232. VulnerableSoftwareTest diff --git a/xref-test/index.html b/xref-test/index.html index 346723553..b14c5d0a6 100644 --- a/xref-test/index.html +++ b/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check 1.3.6 Reference + Dependency-Check 1.4.0 Reference diff --git a/xref-test/org/owasp/dependencycheck/BaseDBTestCase.html b/xref-test/org/owasp/dependencycheck/BaseDBTestCase.html index ba1377c61..8567f8f5d 100644 --- a/xref-test/org/owasp/dependencycheck/BaseDBTestCase.html +++ b/xref-test/org/owasp/dependencycheck/BaseDBTestCase.html @@ -39,8 +39,8 @@ 31 import org.slf4j.LoggerFactory; 32 33 /** -34 * An abstract database test case that is used to ensure the H2 DB exists prior to performing tests that utilize the data -35 * contained within. +34 * An abstract database test case that is used to ensure the H2 DB exists prior +35 * to performing tests that utilize the data contained within. 36 * 37 * @author Jeremy Long 38 */ @@ -57,78 +57,83 @@ 49 50 public static void ensureDBExists() throws Exception { 51 -52 java.io.File dataPath = Settings.getDataDirectory(); -53 String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME); -54 LOGGER.trace("DB file name {}", fileName); -55 java.io.File dataFile = new File(dataPath, fileName); -56 LOGGER.trace("Ensuring {} exists", dataFile.toString()); -57 if (!dataPath.exists() || !dataFile.exists()) { -58 LOGGER.trace("Extracting database to {}", dataPath.toString()); -59 dataPath.mkdirs(); -60 FileInputStream fis = null; -61 ZipInputStream zin = null; -62 try { -63 File path = new File(BaseDBTestCase.class.getClassLoader().getResource("data.zip").getPath()); -64 fis = new FileInputStream(path); -65 zin = new ZipInputStream(new BufferedInputStream(fis)); -66 ZipEntry entry; -67 while ((entry = zin.getNextEntry()) != null) { -68 if (entry.isDirectory()) { -69 final File d = new File(dataPath, entry.getName()); -70 d.mkdir(); -71 continue; -72 } -73 FileOutputStream fos = null; -74 BufferedOutputStream dest = null; -75 try { -76 File o = new File(dataPath, entry.getName()); -77 o.createNewFile(); -78 fos = new FileOutputStream(o, false); -79 dest = new BufferedOutputStream(fos, BUFFER_SIZE); -80 byte data[] = new byte[BUFFER_SIZE]; -81 int count; -82 while ((count = zin.read(data, 0, BUFFER_SIZE)) != -1) { -83 dest.write(data, 0, count); -84 } -85 } catch (Throwable ex) { -86 LOGGER.error("", ex); -87 } finally { -88 try { -89 if (dest != null) { -90 dest.flush(); -91 dest.close(); -92 } -93 } catch (Throwable ex) { -94 LOGGER.trace("", ex); -95 } -96 try { -97 if (fos != null) { -98 fos.close(); -99 } -100 } catch (Throwable ex) { -101 LOGGER.trace("", ex); -102 } -103 } -104 } -105 } finally { -106 try { -107 if (zin != null) { -108 zin.close(); -109 } -110 } catch (Throwable ex) { -111 LOGGER.trace("", ex); -112 } -113 try { -114 if (fis != null) { -115 fis.close(); -116 } -117 } catch (Throwable ex) { -118 LOGGER.trace("", ex); -119 } -120 } -121 } -122 } -123 } +52 File f = new File("./target/data/dc.h2.db"); +53 if (f.exists() && f.isFile() && f.length() < 71680) { +54 f.delete(); +55 } +56 +57 java.io.File dataPath = Settings.getDataDirectory(); +58 String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME); +59 LOGGER.trace("DB file name {}", fileName); +60 java.io.File dataFile = new File(dataPath, fileName); +61 LOGGER.trace("Ensuring {} exists", dataFile.toString()); +62 if (!dataPath.exists() || !dataFile.exists()) { +63 LOGGER.trace("Extracting database to {}", dataPath.toString()); +64 dataPath.mkdirs(); +65 FileInputStream fis = null; +66 ZipInputStream zin = null; +67 try { +68 File path = new File(BaseDBTestCase.class.getClassLoader().getResource("data.zip").getPath()); +69 fis = new FileInputStream(path); +70 zin = new ZipInputStream(new BufferedInputStream(fis)); +71 ZipEntry entry; +72 while ((entry = zin.getNextEntry()) != null) { +73 if (entry.isDirectory()) { +74 final File d = new File(dataPath, entry.getName()); +75 d.mkdir(); +76 continue; +77 } +78 FileOutputStream fos = null; +79 BufferedOutputStream dest = null; +80 try { +81 File o = new File(dataPath, entry.getName()); +82 o.createNewFile(); +83 fos = new FileOutputStream(o, false); +84 dest = new BufferedOutputStream(fos, BUFFER_SIZE); +85 byte data[] = new byte[BUFFER_SIZE]; +86 int count; +87 while ((count = zin.read(data, 0, BUFFER_SIZE)) != -1) { +88 dest.write(data, 0, count); +89 } +90 } catch (Throwable ex) { +91 LOGGER.error("", ex); +92 } finally { +93 try { +94 if (dest != null) { +95 dest.flush(); +96 dest.close(); +97 } +98 } catch (Throwable ex) { +99 LOGGER.trace("", ex); +100 } +101 try { +102 if (fos != null) { +103 fos.close(); +104 } +105 } catch (Throwable ex) { +106 LOGGER.trace("", ex); +107 } +108 } +109 } +110 } finally { +111 try { +112 if (zin != null) { +113 zin.close(); +114 } +115 } catch (Throwable ex) { +116 LOGGER.trace("", ex); +117 } +118 try { +119 if (fis != null) { +120 fis.close(); +121 } +122 } catch (Throwable ex) { +123 LOGGER.trace("", ex); +124 } +125 } +126 } +127 } +128 }
      diff --git a/xref-test/org/owasp/dependencycheck/BaseTest.html b/xref-test/org/owasp/dependencycheck/BaseTest.html index 5f8162d36..d4710042f 100644 --- a/xref-test/org/owasp/dependencycheck/BaseTest.html +++ b/xref-test/org/owasp/dependencycheck/BaseTest.html @@ -47,7 +47,7 @@ 39 if (f.exists() && f.isFile() && f.length() < 71680) { 40 System.err.println("------------------------------------------------"); 41 System.err.println("------------------------------------------------"); -42 System.err.println("I broke the build"); +42 System.err.println("Test referenced CveDB() and does not extend BaseDbTestCases?"); 43 System.err.println("------------------------------------------------"); 44 System.err.println("------------------------------------------------"); 45 } diff --git a/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html b/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html index 5150c701e..eac332370 100644 --- a/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html +++ b/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html @@ -38,41 +38,32 @@ 30 * 31 * @author Jeremy Long 32 */ -33 public class EngineIntegrationTest extends BaseTest { +33 public class EngineIntegrationTest extends BaseDBTestCase { 34 -35 @Before -36 public void setUp() throws Exception { -37 org.owasp.dependencycheck.BaseDBTestCase.ensureDBExists(); -38 } -39 -40 @After -41 public void tearDown() { -42 } -43 -44 /** -45 * Test running the entire engine. -46 * -47 * @throws Exception is thrown when an exception occurs. -48 */ -49 @Test -50 public void testEngine() throws Exception { -51 String testClasses = "target/test-classes"; -52 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -53 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -54 Engine instance = new Engine(); -55 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -56 instance.scan(testClasses); -57 assertTrue(instance.getDependencies().size() > 0); -58 instance.analyzeDependencies(); -59 CveDB cveDB = new CveDB(); -60 cveDB.open(); -61 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); -62 cveDB.close(); -63 ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); -64 rg.generateReports("./target/", "ALL"); -65 instance.cleanup(); -66 } -67 } +35 /** +36 * Test running the entire engine. +37 * +38 * @throws Exception is thrown when an exception occurs. +39 */ +40 @Test +41 public void testEngine() throws Exception { +42 String testClasses = "target/test-classes"; +43 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +44 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +45 Engine instance = new Engine(); +46 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +47 instance.scan(testClasses); +48 assertTrue(instance.getDependencies().size() > 0); +49 instance.analyzeDependencies(); +50 CveDB cveDB = new CveDB(); +51 cveDB.open(); +52 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); +53 cveDB.close(); +54 ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); +55 rg.generateReports("./target/", "ALL"); +56 instance.cleanup(); +57 } +58 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html index 0891773b9..b19c56d9a 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html @@ -85,8 +85,8 @@ 77 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml"); 78 instance.initialize(); 79 int expCount = 5; -80 List<SuppressionRule> result = instance.getRules(); -81 assertTrue(expCount <= result.size()); +80 int currentSize = instance.getRules().size(); +81 assertTrue(expCount <= currentSize); 82 } 83 84 @Test(expected = SuppressionParseException.class) diff --git a/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html b/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html index 771cecd1a..678736ff6 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html @@ -26,34 +26,64 @@ 18 package org.owasp.dependencycheck.analyzer; 19 20 import java.util.Iterator; -21 import static org.junit.Assert.assertTrue; -22 import org.junit.Test; -23 import org.owasp.dependencycheck.BaseTest; -24 -25 /** -26 * -27 * @author Jeremy Long -28 */ -29 public class AnalyzerServiceTest extends BaseTest { -30 -31 /** -32 * Test of getAnalyzers method, of class AnalyzerService. -33 */ -34 @Test -35 public void testGetAnalyzers() { -36 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); -37 Iterator<Analyzer> result = instance.getAnalyzers(); -38 -39 boolean found = false; -40 while (result.hasNext()) { -41 Analyzer a = result.next(); -42 if ("Jar Analyzer".equals(a.getName())) { -43 found = true; -44 } -45 } -46 assertTrue("JarAnalyzer loaded", found); -47 } -48 } +21 import java.util.List; +22 import static org.junit.Assert.assertFalse; +23 import static org.junit.Assert.assertTrue; +24 import org.junit.Test; +25 import org.owasp.dependencycheck.BaseDBTestCase; +26 import org.owasp.dependencycheck.utils.Settings; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public class AnalyzerServiceTest extends BaseDBTestCase { +33 +34 /** +35 * Test of getAnalyzers method, of class AnalyzerService. +36 */ +37 @Test +38 public void testGetAnalyzers() { +39 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); +40 List<Analyzer> result = instance.getAnalyzers(); +41 +42 boolean found = false; +43 for (Analyzer a : result) { +44 if ("Jar Analyzer".equals(a.getName())) { +45 found = true; +46 } +47 } +48 assertTrue("JarAnalyzer loaded", found); +49 } +50 +51 /** +52 * Test of getAnalyzers method, of class AnalyzerService. +53 */ +54 @Test +55 public void testGetExperimentalAnalyzers() { +56 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); +57 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); +58 List<Analyzer> result = instance.getAnalyzers(); +59 String experimental = "CMake Analyzer"; +60 boolean found = false; +61 for (Analyzer a : result) { +62 if (experimental.equals(a.getName())) { +63 found = true; +64 } +65 } +66 assertFalse("Experimental analyzer loaded when set to false", found); +67 +68 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, true); +69 result = instance.getAnalyzers(); +70 found = false; +71 for (Analyzer a : result) { +72 if (experimental.equals(a.getName())) { +73 found = true; +74 } +75 } +76 assertTrue("Experimental analyzer not loaded when set to true", found); +77 } +78 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html b/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html index 6ada26cb3..036e178cb 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html @@ -248,7 +248,7 @@ 240 241 Set<String> vendorWeightings = Collections.singleton("apache"); 242 -243 List<IndexEntry> result = instance.searchCPE(vendor, product, productWeightings, vendorWeightings); +243 List<IndexEntry> result = instance.searchCPE(vendor, product, vendorWeightings, productWeightings); 244 instance.close(); 245 246 boolean found = false; diff --git a/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html index f51f1e85a..2a4d163ba 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html @@ -63,51 +63,52 @@ 55 */ 56 @Before 57 public void setUp() throws Exception { -58 analyzer = new ComposerLockAnalyzer(); -59 analyzer.setFilesMatched(true); -60 analyzer.initialize(); -61 } -62 -63 /** -64 * Cleanup the analyzer's temp files, etc. -65 * -66 * @throws Exception thrown if there is a problem -67 */ -68 @After -69 public void tearDown() throws Exception { -70 analyzer.close(); -71 analyzer = null; -72 } -73 -74 /** -75 * Test of getName method, of class ComposerLockAnalyzer. -76 */ -77 @Test -78 public void testGetName() { -79 assertEquals("Composer.lock analyzer", analyzer.getName()); -80 } -81 -82 /** -83 * Test of supportsExtension method, of class ComposerLockAnalyzer. -84 */ -85 @Test -86 public void testSupportsFiles() { -87 assertTrue(analyzer.accept(new File("composer.lock"))); -88 } -89 -90 /** -91 * Test of inspect method, of class PythonDistributionAnalyzer. -92 * -93 * @throws AnalysisException is thrown when an exception occurs. -94 */ -95 @Test -96 public void testAnalyzePackageJson() throws Exception { -97 final Engine engine = new Engine(); -98 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, -99 "composer.lock")); -100 analyzer.analyze(result, engine); -101 } -102 } +58 super.setUp(); +59 analyzer = new ComposerLockAnalyzer(); +60 analyzer.setFilesMatched(true); +61 analyzer.initialize(); +62 } +63 +64 /** +65 * Cleanup the analyzer's temp files, etc. +66 * +67 * @throws Exception thrown if there is a problem +68 */ +69 @After +70 public void tearDown() throws Exception { +71 analyzer.close(); +72 analyzer = null; +73 } +74 +75 /** +76 * Test of getName method, of class ComposerLockAnalyzer. +77 */ +78 @Test +79 public void testGetName() { +80 assertEquals("Composer.lock analyzer", analyzer.getName()); +81 } +82 +83 /** +84 * Test of supportsExtension method, of class ComposerLockAnalyzer. +85 */ +86 @Test +87 public void testSupportsFiles() { +88 assertTrue(analyzer.accept(new File("composer.lock"))); +89 } +90 +91 /** +92 * Test of inspect method, of class PythonDistributionAnalyzer. +93 * +94 * @throws AnalysisException is thrown when an exception occurs. +95 */ +96 @Test +97 public void testAnalyzePackageJson() throws Exception { +98 final Engine engine = new Engine(); +99 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +100 "composer.lock")); +101 analyzer.analyze(result, engine); +102 } +103 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.html index cbd99ed40..0ece9936c 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.html @@ -26,55 +26,56 @@ 18 import static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertTrue; 20 import org.junit.Test; -21 import org.owasp.dependencycheck.Engine; -22 import org.owasp.dependencycheck.dependency.Dependency; -23 -24 /** -25 * -26 * @author Jeremy Long -27 */ -28 public class FalsePositiveAnalyzerTest { -29 -30 /** -31 * Test of getName method, of class FalsePositiveAnalyzer. -32 */ -33 @Test -34 public void testGetName() { -35 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); -36 String expResult = "False Positive Analyzer"; -37 String result = instance.getName(); -38 assertEquals(expResult, result); -39 } -40 -41 /** -42 * Test of getAnalysisPhase method, of class FalsePositiveAnalyzer. -43 */ -44 @Test -45 public void testGetAnalysisPhase() { -46 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); -47 AnalysisPhase expResult = AnalysisPhase.POST_IDENTIFIER_ANALYSIS; -48 AnalysisPhase result = instance.getAnalysisPhase(); -49 assertEquals(expResult, result); -50 } -51 -52 /** -53 * Test of analyze method, of class FalsePositiveAnalyzer. -54 */ -55 @Test -56 public void testAnalyze() throws Exception { -57 Dependency dependency = new Dependency(); -58 dependency.setFileName("pom.xml"); -59 dependency.setFilePath("pom.xml"); -60 dependency.addIdentifier("cpe", "cpe:/a:file:file:1.2.1", "http://some.org/url"); -61 Engine engine = null; -62 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); -63 int before = dependency.getIdentifiers().size(); -64 instance.analyze(dependency, engine); -65 int after = dependency.getIdentifiers().size(); -66 assertTrue(before > after); -67 } -68 -69 } +21 import org.owasp.dependencycheck.BaseTest; +22 import org.owasp.dependencycheck.Engine; +23 import org.owasp.dependencycheck.dependency.Dependency; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class FalsePositiveAnalyzerTest extends BaseTest { +30 +31 /** +32 * Test of getName method, of class FalsePositiveAnalyzer. +33 */ +34 @Test +35 public void testGetName() { +36 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); +37 String expResult = "False Positive Analyzer"; +38 String result = instance.getName(); +39 assertEquals(expResult, result); +40 } +41 +42 /** +43 * Test of getAnalysisPhase method, of class FalsePositiveAnalyzer. +44 */ +45 @Test +46 public void testGetAnalysisPhase() { +47 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); +48 AnalysisPhase expResult = AnalysisPhase.POST_IDENTIFIER_ANALYSIS; +49 AnalysisPhase result = instance.getAnalysisPhase(); +50 assertEquals(expResult, result); +51 } +52 +53 /** +54 * Test of analyze method, of class FalsePositiveAnalyzer. +55 */ +56 @Test +57 public void testAnalyze() throws Exception { +58 Dependency dependency = new Dependency(); +59 dependency.setFileName("pom.xml"); +60 dependency.setFilePath("pom.xml"); +61 dependency.addIdentifier("cpe", "cpe:/a:file:file:1.2.1", "http://some.org/url"); +62 Engine engine = null; +63 FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer(); +64 int before = dependency.getIdentifiers().size(); +65 instance.analyze(dependency, engine); +66 int after = dependency.getIdentifiers().size(); +67 assertTrue(before > after); +68 } +69 +70 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.html index 3d0554733..0e00d4786 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.html @@ -36,7 +36,7 @@ 28 * 29 * @author Jeremy Long 30 */ -31 public class FileNameAnalyzerTest { +31 public class FileNameAnalyzerTest extends BaseTest { 32 33 /** 34 * Test of getName method, of class FileNameAnalyzer. diff --git a/xref-test/org/owasp/dependencycheck/analyzer/JarAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/JarAnalyzerTest.html index c3ab8d23a..69a15ad1a 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/JarAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/JarAnalyzerTest.html @@ -25,115 +25,130 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import org.junit.Test; -21 import org.owasp.dependencycheck.BaseTest; -22 import org.owasp.dependencycheck.dependency.Dependency; -23 import org.owasp.dependencycheck.dependency.Evidence; -24 -25 import java.io.File; -26 import java.util.ArrayList; -27 import java.util.List; -28 -29 import static org.junit.Assert.assertEquals; -30 import static org.junit.Assert.assertTrue; +20 import static org.junit.Assert.assertEquals; +21 import static org.junit.Assert.assertTrue; +22 +23 import java.io.File; +24 import java.util.ArrayList; +25 import java.util.List; +26 +27 import org.junit.Test; +28 import org.owasp.dependencycheck.BaseTest; +29 import org.owasp.dependencycheck.dependency.Dependency; +30 import org.owasp.dependencycheck.dependency.Evidence; 31 32 /** 33 * @author Jeremy Long 34 */ 35 public class JarAnalyzerTest extends BaseTest { 36 -37 /** -38 * Test of inspect method, of class JarAnalyzer. -39 * -40 * @throws Exception is thrown when an exception occurs. -41 */ -42 @Test -43 public void testAnalyze() throws Exception { -44 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -45 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -46 Dependency result = new Dependency(file); -47 JarAnalyzer instance = new JarAnalyzer(); -48 instance.analyze(result, null); -49 assertTrue(result.getVendorEvidence().toString().toLowerCase().contains("apache")); -50 assertTrue(result.getVendorEvidence().getWeighting().contains("apache")); -51 -52 //file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); -53 file = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar"); -54 result = new Dependency(file); -55 instance.analyze(result, null); -56 boolean found = false; -57 for (Evidence e : result.getProductEvidence()) { -58 if (e.getName().equalsIgnoreCase("package-title") -59 && e.getValue().equalsIgnoreCase("org.mortbay.http")) { -60 found = true; -61 break; -62 } -63 } -64 assertTrue("package-title of org.mortbay.http not found in org.mortbay.jetty.jar", found); -65 -66 found = false; -67 for (Evidence e : result.getVendorEvidence()) { -68 if (e.getName().equalsIgnoreCase("implementation-url") -69 && e.getValue().equalsIgnoreCase("http://jetty.mortbay.org")) { -70 found = true; -71 break; -72 } -73 } -74 assertTrue("implementation-url of http://jetty.mortbay.org not found in org.mortbay.jetty.jar", found); -75 -76 found = false; -77 for (Evidence e : result.getVersionEvidence()) { -78 if (e.getName().equalsIgnoreCase("Implementation-Version") -79 && e.getValue().equalsIgnoreCase("4.2.27")) { -80 found = true; -81 break; -82 } -83 } -84 assertTrue("implementation-version of 4.2.27 not found in org.mortbay.jetty.jar", found); -85 -86 //file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jmx.jar").getPath()); -87 file = BaseTest.getResourceAsFile(this, "org.mortbay.jmx.jar"); -88 result = new Dependency(file); -89 instance.analyze(result, null); -90 assertEquals("org.mortbar.jmx.jar has version evidence?", result.getVersionEvidence().size(), 0); -91 } -92 -93 /** -94 * Test of getSupportedExtensions method, of class JarAnalyzer. -95 */ -96 @Test -97 public void testAcceptSupportedExtensions() throws Exception { -98 JarAnalyzer instance = new JarAnalyzer(); -99 instance.initialize(); -100 instance.setEnabled(true); -101 String[] files = {"test.jar", "test.war"}; -102 for (String name : files) { -103 assertTrue(name, instance.accept(new File(name))); -104 } -105 } -106 -107 /** -108 * Test of getName method, of class JarAnalyzer. -109 */ -110 @Test -111 public void testGetName() { -112 JarAnalyzer instance = new JarAnalyzer(); -113 String expResult = "Jar Analyzer"; -114 String result = instance.getName(); -115 assertEquals(expResult, result); -116 } -117 -118 @Test -119 public void testParseManifest() throws Exception { -120 File file = BaseTest.getResourceAsFile(this, "xalan-2.7.0.jar"); -121 Dependency result = new Dependency(file); -122 JarAnalyzer instance = new JarAnalyzer(); -123 List<JarAnalyzer.ClassNameInformation> cni = new ArrayList<JarAnalyzer.ClassNameInformation>(); -124 instance.parseManifest(result, cni); -125 -126 assertTrue(result.getVersionEvidence().getEvidence("manifest: org/apache/xalan/").size() > 0); -127 } -128 } +37 // private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzerTest.class); +38 +39 /** +40 * Test of inspect method, of class JarAnalyzer. +41 * +42 * @throws Exception is thrown when an exception occurs. +43 */ +44 @Test +45 public void testAnalyze() throws Exception { +46 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +47 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +48 Dependency result = new Dependency(file); +49 JarAnalyzer instance = new JarAnalyzer(); +50 instance.analyze(result, null); +51 assertTrue(result.getVendorEvidence().toString().toLowerCase().contains("apache")); +52 assertTrue(result.getVendorEvidence().getWeighting().contains("apache")); +53 +54 file = BaseTest.getResourceAsFile(this, "dwr.jar"); +55 result = new Dependency(file); +56 instance.analyze(result, null); +57 boolean found = false; +58 for (Evidence e : result.getVendorEvidence()) { +59 if (e.getName().equals("url")) { +60 assertEquals("Project url was not as expected in dwr.jar", e.getValue(), "http://getahead.ltd.uk/dwr"); +61 found = true; +62 break; +63 } +64 } +65 assertTrue("Project url was not found in dwr.jar", found); +66 +67 //file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); +68 file = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar"); +69 result = new Dependency(file); +70 instance.analyze(result, null); +71 found = false; +72 for (Evidence e : result.getProductEvidence()) { +73 if (e.getName().equalsIgnoreCase("package-title") +74 && e.getValue().equalsIgnoreCase("org.mortbay.http")) { +75 found = true; +76 break; +77 } +78 } +79 assertTrue("package-title of org.mortbay.http not found in org.mortbay.jetty.jar", found); +80 +81 found = false; +82 for (Evidence e : result.getVendorEvidence()) { +83 if (e.getName().equalsIgnoreCase("implementation-url") +84 && e.getValue().equalsIgnoreCase("http://jetty.mortbay.org")) { +85 found = true; +86 break; +87 } +88 } +89 assertTrue("implementation-url of http://jetty.mortbay.org not found in org.mortbay.jetty.jar", found); +90 +91 found = false; +92 for (Evidence e : result.getVersionEvidence()) { +93 if (e.getName().equalsIgnoreCase("Implementation-Version") +94 && e.getValue().equalsIgnoreCase("4.2.27")) { +95 found = true; +96 break; +97 } +98 } +99 assertTrue("implementation-version of 4.2.27 not found in org.mortbay.jetty.jar", found); +100 +101 //file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jmx.jar").getPath()); +102 file = BaseTest.getResourceAsFile(this, "org.mortbay.jmx.jar"); +103 result = new Dependency(file); +104 instance.analyze(result, null); +105 assertEquals("org.mortbar.jmx.jar has version evidence?", result.getVersionEvidence().size(), 0); +106 } +107 +108 /** +109 * Test of getSupportedExtensions method, of class JarAnalyzer. +110 */ +111 @Test +112 public void testAcceptSupportedExtensions() throws Exception { +113 JarAnalyzer instance = new JarAnalyzer(); +114 instance.initialize(); +115 instance.setEnabled(true); +116 String[] files = {"test.jar", "test.war"}; +117 for (String name : files) { +118 assertTrue(name, instance.accept(new File(name))); +119 } +120 } +121 +122 /** +123 * Test of getName method, of class JarAnalyzer. +124 */ +125 @Test +126 public void testGetName() { +127 JarAnalyzer instance = new JarAnalyzer(); +128 String expResult = "Jar Analyzer"; +129 String result = instance.getName(); +130 assertEquals(expResult, result); +131 } +132 +133 @Test +134 public void testParseManifest() throws Exception { +135 File file = BaseTest.getResourceAsFile(this, "xalan-2.7.0.jar"); +136 Dependency result = new Dependency(file); +137 JarAnalyzer instance = new JarAnalyzer(); +138 List<JarAnalyzer.ClassNameInformation> cni = new ArrayList<JarAnalyzer.ClassNameInformation>(); +139 instance.parseManifest(result, cni); +140 +141 assertTrue(result.getVersionEvidence().getEvidence("manifest: org/apache/xalan/").size() > 0); +142 } +143 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html index eb035d832..1a4f76d87 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html @@ -26,126 +26,211 @@ 18 package org.owasp.dependencycheck.analyzer; 19 20 import static org.hamcrest.CoreMatchers.is; -21 import static org.junit.Assert.assertThat; -22 import static org.junit.Assert.assertTrue; -23 -24 import java.io.File; -25 -26 import org.junit.After; -27 import org.junit.Assume; -28 import org.junit.Before; -29 import org.junit.Test; -30 import org.owasp.dependencycheck.BaseTest; -31 import org.owasp.dependencycheck.Engine; -32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -33 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.utils.Settings; -36 import org.slf4j.Logger; -37 import org.slf4j.LoggerFactory; -38 -39 /** -40 * Unit tests for {@link RubyBundleAuditAnalyzer}. -41 * -42 * @author Dale Visser -43 */ -44 public class RubyBundleAuditAnalyzerTest extends BaseTest { -45 -46 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); -47 -48 /** -49 * The analyzer to test. -50 */ -51 RubyBundleAuditAnalyzer analyzer; -52 -53 /** -54 * Correctly setup the analyzer for testing. -55 * -56 * @throws Exception thrown if there is a problem -57 */ -58 @Before -59 public void setUp() throws Exception { -60 Settings.initialize(); -61 analyzer = new RubyBundleAuditAnalyzer(); -62 analyzer.setFilesMatched(true); -63 } -64 -65 /** -66 * Cleanup the analyzer's temp files, etc. -67 * -68 * @throws Exception thrown if there is a problem -69 */ -70 @After -71 public void tearDown() throws Exception { -72 Settings.cleanup(); -73 analyzer.close(); -74 analyzer = null; -75 } -76 -77 /** -78 * Test Ruby Gemspec name. -79 */ -80 @Test -81 public void testGetName() { -82 assertThat(analyzer.getName(), is("Ruby Bundle Audit Analyzer")); -83 } -84 -85 /** -86 * Test Ruby Bundler Audit file support. -87 */ -88 @Test -89 public void testSupportsFiles() { -90 assertThat(analyzer.accept(new File("Gemfile.lock")), is(true)); -91 } -92 -93 /** -94 * Test Ruby BundlerAudit analysis. -95 * -96 * @throws AnalysisException is thrown when an exception occurs. +21 import static org.junit.Assert.assertEquals; +22 import static org.junit.Assert.assertThat; +23 import static org.junit.Assert.assertTrue; +24 +25 import java.io.File; +26 import java.util.Iterator; +27 import java.util.List; +28 import java.util.Set; +29 +30 import org.junit.After; +31 import org.junit.Assume; +32 import org.junit.Before; +33 import org.junit.Test; +34 import org.owasp.dependencycheck.BaseDBTestCase; +35 import org.owasp.dependencycheck.BaseTest; +36 import org.owasp.dependencycheck.Engine; +37 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +38 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +39 import org.owasp.dependencycheck.dependency.Dependency; +40 import org.owasp.dependencycheck.dependency.Evidence; +41 import org.owasp.dependencycheck.dependency.Identifier; +42 import org.owasp.dependencycheck.dependency.Vulnerability; +43 import org.owasp.dependencycheck.utils.Settings; +44 import org.slf4j.Logger; +45 import org.slf4j.LoggerFactory; +46 +47 /** +48 * Unit tests for {@link RubyBundleAuditAnalyzer}. +49 * +50 * @author Dale Visser +51 */ +52 public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { +53 +54 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); +55 +56 /** +57 * The analyzer to test. +58 */ +59 RubyBundleAuditAnalyzer analyzer; +60 +61 /** +62 * Correctly setup the analyzer for testing. +63 * +64 * @throws Exception thrown if there is a problem +65 */ +66 @Before +67 public void setUp() throws Exception { +68 super.setUp(); +69 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +70 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +71 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +72 analyzer = new RubyBundleAuditAnalyzer(); +73 analyzer.setFilesMatched(true); +74 } +75 +76 /** +77 * Cleanup the analyzer's temp files, etc. +78 * +79 * @throws Exception thrown if there is a problem +80 */ +81 @After +82 public void tearDown() throws Exception { +83 analyzer.close(); +84 analyzer = null; +85 } +86 +87 /** +88 * Test Ruby Gemspec name. +89 */ +90 @Test +91 public void testGetName() { +92 assertThat(analyzer.getName(), is("Ruby Bundle Audit Analyzer")); +93 } +94 +95 /** +96 * Test Ruby Bundler Audit file support. 97 */ 98 @Test -99 public void testAnalysis() throws AnalysisException, DatabaseException { -100 try { -101 analyzer.initialize(); +99 public void testSupportsFiles() { +100 assertThat(analyzer.accept(new File("Gemfile.lock")), is(true)); +101 } 102 -103 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, -104 "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock")); -105 final Engine engine = new Engine(); -106 analyzer.analyze(result, engine); -107 int size = engine.getDependencies().size(); -108 assertThat(size, is(1)); -109 -110 Dependency dependency = engine.getDependencies().get(0); -111 assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); -112 assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); -113 -114 } catch (Exception e) { -115 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); -116 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); -117 } -118 } +103 /** +104 * Test Ruby BundlerAudit analysis. +105 * +106 * @throws AnalysisException is thrown when an exception occurs. +107 */ +108 @Test +109 public void testAnalysis() throws AnalysisException, DatabaseException { +110 try { +111 analyzer.initialize(); +112 final String resource = "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock"; +113 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, resource)); +114 final Engine engine = new Engine(); +115 analyzer.analyze(result, engine); +116 int size = engine.getDependencies().size(); +117 +118 assertTrue(size >= 1); 119 -120 /** -121 * Test when Ruby bundle-audit is not available on the system. -122 * -123 * @throws AnalysisException is thrown when an exception occurs. -124 */ -125 @Test -126 public void testMissingBundleAudit() throws AnalysisException, DatabaseException { -127 //set a non-exist bundle-audit -128 Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit"); -129 try { -130 //initialize should fail. -131 analyzer.initialize(); -132 } catch (Exception e) { -133 //expected, so ignore. -134 } -135 finally { -136 assertThat(analyzer.isEnabled(), is(false)); -137 LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); -138 } -139 } -140 } +120 Dependency dependency = engine.getDependencies().get(0); +121 assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); +122 assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); +123 assertTrue(dependency.getFilePath().endsWith(resource)); +124 assertTrue(dependency.getFileName().equals("Gemfile.lock")); +125 } catch (Exception e) { +126 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\"."); +127 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); +128 } +129 } +130 +131 /** +132 * Test Ruby addCriticalityToVulnerability +133 */ +134 @Test +135 public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { +136 try { +137 analyzer.initialize(); +138 +139 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +140 "ruby/vulnerable/gems/sinatra/Gemfile.lock")); +141 final Engine engine = new Engine(); +142 analyzer.analyze(result, engine); +143 +144 Dependency dependency = engine.getDependencies().get(0); +145 Vulnerability vulnerability = dependency.getVulnerabilities().first(); +146 assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); +147 +148 } catch (Exception e) { +149 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); +150 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); +151 } +152 } +153 +154 /** +155 * Test when Ruby bundle-audit is not available on the system. +156 * +157 * @throws AnalysisException is thrown when an exception occurs. +158 */ +159 @Test +160 public void testMissingBundleAudit() throws AnalysisException, DatabaseException { +161 //set a non-exist bundle-audit +162 Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit"); +163 try { +164 //initialize should fail. +165 analyzer.initialize(); +166 } catch (Exception e) { +167 //expected, so ignore. +168 } finally { +169 assertThat(analyzer.isEnabled(), is(false)); +170 LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); +171 } +172 } +173 +174 /** +175 * Test Ruby dependencies and their paths. +176 * +177 * @throws AnalysisException is thrown when an exception occurs. +178 */ +179 @Test +180 public void testDependenciesPath() throws AnalysisException, DatabaseException { +181 final Engine engine = new Engine(); +182 engine.scan(BaseTest.getResourceAsFile(this, +183 "ruby/vulnerable/gems/rails-4.1.15/")); +184 try { +185 engine.analyzeDependencies(); +186 } catch (NullPointerException ex) { +187 LOGGER.error("NPE", ex); +188 throw ex; +189 } +190 List<Dependency> dependencies = engine.getDependencies(); +191 LOGGER.info(dependencies.size() + " dependencies found."); +192 Iterator<Dependency> dIterator = dependencies.iterator(); +193 while (dIterator.hasNext()) { +194 Dependency dept = dIterator.next(); +195 LOGGER.info("dept path: " + dept.getActualFilePath()); +196 +197 Set<Identifier> identifiers = dept.getIdentifiers(); +198 Iterator<Identifier> idIterator = identifiers.iterator(); +199 while (idIterator.hasNext()) { +200 Identifier id = idIterator.next(); +201 LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); +202 } +203 +204 Set<Evidence> prodEv = dept.getProductEvidence().getEvidence(); +205 Iterator<Evidence> it = prodEv.iterator(); +206 while (it.hasNext()) { +207 Evidence e = it.next(); +208 LOGGER.info(" prod: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +209 } +210 Set<Evidence> versionEv = dept.getVersionEvidence().getEvidence(); +211 Iterator<Evidence> vIt = versionEv.iterator(); +212 while (vIt.hasNext()) { +213 Evidence e = vIt.next(); +214 LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +215 } +216 +217 Set<Evidence> vendorEv = dept.getVendorEvidence().getEvidence(); +218 Iterator<Evidence> vendorIt = vendorEv.iterator(); +219 while (vendorIt.hasNext()) { +220 Evidence e = vendorIt.next(); +221 LOGGER.info(" vendor: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +222 } +223 } +224 } +225 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzerTest.html new file mode 100644 index 000000000..bfa703e57 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzerTest.html @@ -0,0 +1,119 @@ + + + +RubyBundlerAnalyzerTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +3    *
      +4    * Licensed under the Apache License, Version 2.0 (the "License");
      +5    * you may not use this file except in compliance with the License.
      +6    * You may obtain a copy of the License at
      +7    *
      +8    *     http://www.apache.org/licenses/LICENSE-2.0
      +9    *
      +10   * Unless required by applicable law or agreed to in writing, software
      +11   * distributed under the License is distributed on an "AS IS" BASIS,
      +12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      +13   * See the License for the specific language governing permissions and
      +14   * limitations under the License.
      +15   *
      +16   * Copyright (c) 2016 Bianca Jiang. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.analyzer;
      +19  
      +20  import org.junit.After;
      +21  import org.junit.Before;
      +22  import org.junit.Test;
      +23  import org.owasp.dependencycheck.BaseTest;
      +24  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      +25  import org.owasp.dependencycheck.dependency.Dependency;
      +26  
      +27  import java.io.File;
      +28  
      +29  import static org.hamcrest.CoreMatchers.containsString;
      +30  import static org.hamcrest.CoreMatchers.is;
      +31  import static org.junit.Assert.*;
      +32  
      +33  /**
      +34   * Unit tests for {@link RubyBundlerAnalyzer}.
      +35   *
      +36   * @author Bianca Jiang
      +37   */
      +38  public class RubyBundlerAnalyzerTest extends BaseTest {
      +39  
      +40      /**
      +41       * The analyzer to test.
      +42       */
      +43      RubyBundlerAnalyzer analyzer;
      +44  
      +45      /**
      +46       * Correctly setup the analyzer for testing.
      +47       *
      +48       * @throws Exception thrown if there is a problem
      +49       */
      +50      @Before
      +51      public void setUp() throws Exception {
      +52          analyzer = new RubyBundlerAnalyzer();
      +53          analyzer.setFilesMatched(true);
      +54          analyzer.initialize();
      +55      }
      +56  
      +57      /**
      +58       * Cleanup the analyzer's temp files, etc.
      +59       *
      +60       * @throws Exception thrown if there is a problem
      +61       */
      +62      @After
      +63      public void tearDown() throws Exception {
      +64          analyzer.close();
      +65          analyzer = null;
      +66      }
      +67  
      +68      /**
      +69       * Test Analyzer name.
      +70       */
      +71      @Test
      +72      public void testGetName() {
      +73          assertThat(analyzer.getName(), is("Ruby Bundler Analyzer"));
      +74      }
      +75  
      +76      /**
      +77       * Test Ruby Gemspec file support.
      +78       */
      +79      @Test
      +80      public void testSupportsFiles() {
      +81          assertThat(analyzer.accept(new File("test.gemspec")), is(false));
      +82          assertThat(analyzer.accept(new File("specifications" + File.separator + "test.gemspec")), is(true));
      +83      }
      +84  
      +85      /**
      +86       * Test Ruby Bundler created gemspec analysis.
      +87       *
      +88       * @throws AnalysisException is thrown when an exception occurs.
      +89       */
      +90      @Test
      +91      public void testAnalyzeGemspec() throws AnalysisException {
      +92          final Dependency result = new Dependency(BaseTest.getResourceAsFile(this,
      +93                  "ruby/vulnerable/gems/rails-4.1.15/vendor/bundle/ruby/2.2.0/specifications/dalli-2.7.5.gemspec"));
      +94          analyzer.analyze(result, null);
      +95          
      +96          final String vendorString = result.getVendorEvidence().toString();
      +97          assertThat(vendorString, containsString("Peter M. Goldstein"));
      +98          assertThat(vendorString, containsString("Mike Perham"));
      +99          assertThat(vendorString, containsString("peter.m.goldstein@gmail.com"));
      +100         assertThat(vendorString, containsString("https://github.com/petergoldstein/dalli"));
      +101         assertThat(vendorString, containsString("MIT"));
      +102         assertThat(result.getProductEvidence().toString(), containsString("dalli"));
      +103         assertThat(result.getProductEvidence().toString(), containsString("High performance memcached client for Ruby"));
      +104         assertThat(result.getVersionEvidence().toString(), containsString("2.7.5"));
      +105     }
      +106 }
      +
      +
      + + + diff --git a/xref-test/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.html index 91ecb8244..f94636973 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.html @@ -87,7 +87,7 @@ 79 @Test 80 public void testSupportsFiles() { 81 assertThat(analyzer.accept(new File("test.gemspec")), is(true)); -82 assertThat(analyzer.accept(new File("Rakefile")), is(true)); +82 // assertThat(analyzer.accept(new File("Rakefile")), is(true)); 83 } 84 85 /** @@ -108,7 +108,20 @@ 100 assertThat(result.getProductEvidence().toString(), containsString("rest-client")); 101 assertThat(result.getVersionEvidence().toString(), containsString("1.7.2")); 102 } -103 } +103 +104 /** +105 * Test Rakefile analysis. +106 * +107 * @throws AnalysisException is thrown when an exception occurs. +108 */ +109 //@Test TODO: place holder to test Rakefile support +110 public void testAnalyzeRakefile() throws AnalysisException { +111 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +112 "ruby/vulnerable/gems/rails-4.1.15/vendor/bundle/ruby/2.2.0/gems/pg-0.18.4/Rakefile")); +113 analyzer.analyze(result, null); +114 //TODO add verification +115 } +116 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html b/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html index 89068d62a..eb9729874 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer @@ -83,6 +83,9 @@
    233. RubyBundleAuditAnalyzerTest +
    234. +
    235. + RubyBundlerAnalyzerTest
    236. RubyGemspecAnalyzerTest diff --git a/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html b/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html index fd4a07b60..9ac987b63 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer @@ -149,6 +149,11 @@ RubyBundleAuditAnalyzerTest + + + + RubyBundlerAnalyzerTest + diff --git a/xref-test/org/owasp/dependencycheck/data/central/package-frame.html b/xref-test/org/owasp/dependencycheck/data/central/package-frame.html index 3c946efdf..776831710 100644 --- a/xref-test/org/owasp/dependencycheck/data/central/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/central/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.central diff --git a/xref-test/org/owasp/dependencycheck/data/central/package-summary.html b/xref-test/org/owasp/dependencycheck/data/central/package-summary.html index 6b58b845f..781eabaff 100644 --- a/xref-test/org/owasp/dependencycheck/data/central/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/central/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.central diff --git a/xref-test/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.html b/xref-test/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.html index 63d364f69..201047b30 100644 --- a/xref-test/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.html +++ b/xref-test/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.html @@ -33,48 +33,49 @@ 25 import java.nio.charset.Charset; 26 27 import static org.junit.Assert.*; -28 -29 /** -30 * Created by colezlaw on 9/5/15. -31 */ -32 public class ComposerLockParserTest { -33 -34 private InputStream inputStream; -35 -36 @Before -37 public void setUp() { -38 inputStream = this.getClass().getClassLoader().getResourceAsStream("composer.lock"); -39 } -40 -41 @Test -42 public void testValidComposerLock() { -43 ComposerLockParser clp = new ComposerLockParser(inputStream); -44 clp.process(); -45 assertEquals(30, clp.getDependencies().size()); -46 assertTrue(clp.getDependencies().contains(new ComposerDependency("symfony", "translation", "2.7.3"))); -47 } -48 -49 @Test(expected = ComposerException.class) -50 public void testNotJSON() throws Exception { -51 String input = "NOT VALID JSON"; -52 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); -53 clp.process(); -54 } -55 -56 @Test(expected = ComposerException.class) -57 public void testNotComposer() throws Exception { -58 String input = "[\"ham\",\"eggs\"]"; -59 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); -60 clp.process(); -61 } -62 -63 @Test(expected = ComposerException.class) -64 public void testNotPackagesArray() throws Exception { -65 String input = "{\"packages\":\"eleventy\"}"; -66 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); -67 clp.process(); -68 } -69 } +28 import org.owasp.dependencycheck.BaseTest; +29 +30 /** +31 * Created by colezlaw on 9/5/15. +32 */ +33 public class ComposerLockParserTest extends BaseTest { +34 +35 private InputStream inputStream; +36 +37 @Before +38 public void setUp() { +39 inputStream = this.getClass().getClassLoader().getResourceAsStream("composer.lock"); +40 } +41 +42 @Test +43 public void testValidComposerLock() { +44 ComposerLockParser clp = new ComposerLockParser(inputStream); +45 clp.process(); +46 assertEquals(30, clp.getDependencies().size()); +47 assertTrue(clp.getDependencies().contains(new ComposerDependency("symfony", "translation", "2.7.3"))); +48 } +49 +50 @Test(expected = ComposerException.class) +51 public void testNotJSON() throws Exception { +52 String input = "NOT VALID JSON"; +53 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); +54 clp.process(); +55 } +56 +57 @Test(expected = ComposerException.class) +58 public void testNotComposer() throws Exception { +59 String input = "[\"ham\",\"eggs\"]"; +60 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); +61 clp.process(); +62 } +63 +64 @Test(expected = ComposerException.class) +65 public void testNotPackagesArray() throws Exception { +66 String input = "{\"packages\":\"eleventy\"}"; +67 ComposerLockParser clp = new ComposerLockParser(new ByteArrayInputStream(input.getBytes(Charset.defaultCharset()))); +68 clp.process(); +69 } +70 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html b/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html index 77aa039f9..57df0ae96 100644 --- a/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.composer diff --git a/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html b/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html index 05fcdb5f4..6a25f9329 100644 --- a/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.composer diff --git a/xref-test/org/owasp/dependencycheck/data/cpe/IndexEntryTest.html b/xref-test/org/owasp/dependencycheck/data/cpe/IndexEntryTest.html index 5fdb42332..f5a0eef05 100644 --- a/xref-test/org/owasp/dependencycheck/data/cpe/IndexEntryTest.html +++ b/xref-test/org/owasp/dependencycheck/data/cpe/IndexEntryTest.html @@ -27,29 +27,30 @@ 19 20 import org.junit.Assert; 21 import org.junit.Test; -22 -23 /** -24 * -25 * @author Jeremy Long -26 */ -27 public class IndexEntryTest { -28 -29 /** -30 * Test of setName method, of class IndexEntry. -31 * -32 * @throws Exception is thrown when an exception occurs. -33 */ -34 @Test -35 public void testSetName() throws Exception { -36 String name = "cpe:/a:apache:struts:1.1:rc2"; -37 -38 IndexEntry instance = new IndexEntry(); -39 instance.parseName(name); -40 -41 Assert.assertEquals("apache", instance.getVendor()); -42 Assert.assertEquals("struts", instance.getProduct()); -43 } -44 } +22 import org.owasp.dependencycheck.BaseTest; +23 +24 /** +25 * +26 * @author Jeremy Long +27 */ +28 public class IndexEntryTest extends BaseTest { +29 +30 /** +31 * Test of setName method, of class IndexEntry. +32 * +33 * @throws Exception is thrown when an exception occurs. +34 */ +35 @Test +36 public void testSetName() throws Exception { +37 String name = "cpe:/a:apache:struts:1.1:rc2"; +38 +39 IndexEntry instance = new IndexEntry(); +40 instance.parseName(name); +41 +42 Assert.assertEquals("apache", instance.getVendor()); +43 Assert.assertEquals("struts", instance.getProduct()); +44 } +45 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html b/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html index dacee8569..4f6c93411 100644 --- a/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html b/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html index 71eaa116a..c2d088727 100644 --- a/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html b/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html index 07379915f..4ce949ccd 100644 --- a/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html +++ b/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html @@ -31,78 +31,60 @@ 23 import org.junit.Before; 24 import org.junit.BeforeClass; 25 import org.junit.Test; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class CweDBTest { -32 -33 public CweDBTest() { -34 } -35 -36 @BeforeClass -37 public static void setUpClass() throws Exception { -38 } -39 -40 @AfterClass -41 public static void tearDownClass() throws Exception { -42 } -43 -44 @Before -45 public void setUp() { -46 } -47 -48 @After -49 public void tearDown() { -50 } -51 -52 /** -53 * Method to serialize the CWE HashMap. This is not used in production; this is only used once during dev to create -54 * the serialized HashMap. -55 */ -56 // @Test -57 // public void testUpdate() throws Exception { -58 // SAXParserFactory factory = SAXParserFactory.newInstance(); -59 // SAXParser saxParser = factory.newSAXParser(); -60 // -61 // CweHandler handler = new CweHandler(); -62 // //File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath()); -63 // File file = new File(this.getClass().getClassLoader().getResource("cwec_v2.5.xml").getPath()); -64 // -65 // saxParser.parse(file, handler); -66 // System.out.println("Found " + handler.getCwe().size() + " cwe entries."); -67 // Map<String, String> cwe = handler.getCwe(); -68 //// FileOutputStream fout = new FileOutputStream("target/current.csv"); -69 //// //FileOutputStream fout = new FileOutputStream("target/new.csv"); -70 //// PrintWriter writer = new PrintWriter(fout); -71 //// for (Map.Entry<String, String> entry : cwe.entrySet()) { -72 //// writer.print('"'); -73 //// writer.print(entry.getKey()); -74 //// writer.print('"'); -75 //// writer.print(','); -76 //// writer.print('"'); -77 //// writer.print(entry.getValue()); -78 //// writer.println('"'); -79 //// } -80 //// writer.close(); -81 // -82 // FileOutputStream fout = new FileOutputStream("src/main/resources/data/cwe.hashmap.serialized"); -83 // ObjectOutputStream objOut = new ObjectOutputStream(fout); -84 // objOut.writeObject(cwe); -85 // objOut.close(); -86 // } -87 /** -88 * Test of getCweName method, of class CweDB. -89 */ -90 @Test -91 public void testGetCweName() { -92 String cweId = "CWE-16"; -93 String expResult = "Configuration"; -94 String result = CweDB.getCweName(cweId); -95 assertEquals(expResult, result); -96 } -97 } +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public class CweDBTest extends BaseTest { +33 +34 /** +35 * Method to serialize the CWE HashMap. This is not used in production; this is only used once during dev to create +36 * the serialized HashMap. +37 */ +38 // @Test +39 // public void testUpdate() throws Exception { +40 // SAXParserFactory factory = SAXParserFactory.newInstance(); +41 // SAXParser saxParser = factory.newSAXParser(); +42 // +43 // CweHandler handler = new CweHandler(); +44 // //File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath()); +45 // File file = new File(this.getClass().getClassLoader().getResource("cwec_v2.5.xml").getPath()); +46 // +47 // saxParser.parse(file, handler); +48 // System.out.println("Found " + handler.getCwe().size() + " cwe entries."); +49 // Map<String, String> cwe = handler.getCwe(); +50 //// FileOutputStream fout = new FileOutputStream("target/current.csv"); +51 //// //FileOutputStream fout = new FileOutputStream("target/new.csv"); +52 //// PrintWriter writer = new PrintWriter(fout); +53 //// for (Map.Entry<String, String> entry : cwe.entrySet()) { +54 //// writer.print('"'); +55 //// writer.print(entry.getKey()); +56 //// writer.print('"'); +57 //// writer.print(','); +58 //// writer.print('"'); +59 //// writer.print(entry.getValue()); +60 //// writer.println('"'); +61 //// } +62 //// writer.close(); +63 // +64 // FileOutputStream fout = new FileOutputStream("src/main/resources/data/cwe.hashmap.serialized"); +65 // ObjectOutputStream objOut = new ObjectOutputStream(fout); +66 // objOut.writeObject(cwe); +67 // objOut.close(); +68 // } +69 /** +70 * Test of getCweName method, of class CweDB. +71 */ +72 @Test +73 public void testGetCweName() { +74 String cweId = "CWE-16"; +75 String expResult = "Configuration"; +76 String result = CweDB.getCweName(cweId); +77 assertEquals(expResult, result); +78 } +79 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html b/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html index 5db18032f..481940f04 100644 --- a/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html b/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html index 9b171a0b2..e5a18da6c 100644 --- a/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html index f7f01c877..72486401a 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html @@ -51,89 +51,74 @@ 43 import org.junit.Before; 44 import org.junit.BeforeClass; 45 import org.junit.Test; -46 -47 /** -48 * -49 * @author Jeremy Long -50 */ -51 public class FieldAnalyzerTest { -52 -53 @BeforeClass -54 public static void setUpClass() throws Exception { -55 } +46 import org.owasp.dependencycheck.BaseTest; +47 +48 /** +49 * +50 * @author Jeremy Long +51 */ +52 public class FieldAnalyzerTest extends BaseTest { +53 +54 @Test +55 public void testAnalyzers() throws Exception { 56 -57 @AfterClass -58 public static void tearDownClass() throws Exception { -59 } -60 -61 @Before -62 public void setUp() { -63 } -64 -65 @After -66 public void tearDown() { -67 } -68 -69 @Test -70 public void testAnalyzers() throws Exception { -71 -72 Analyzer analyzer = new FieldAnalyzer(LuceneUtils.CURRENT_VERSION); -73 Directory index = new RAMDirectory(); -74 -75 String field1 = "product"; -76 String text1 = "springframework"; -77 -78 String field2 = "vendor"; -79 String text2 = "springsource"; -80 -81 createIndex(analyzer, index, field1, text1, field2, text2); -82 -83 //Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -84 String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)"; -85 -86 SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -87 SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -88 HashMap<String, Analyzer> map = new HashMap<String, Analyzer>(); -89 map.put(field1, searchAnalyzerProduct); -90 map.put(field2, searchAnalyzerVendor); -91 PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map); -92 QueryParser parser = new QueryParser(LuceneUtils.CURRENT_VERSION, field1, wrapper); -93 -94 Query q = parser.parse(querystr); -95 //System.out.println(q.toString()); -96 -97 int hitsPerPage = 10; -98 -99 IndexReader reader = DirectoryReader.open(index); -100 IndexSearcher searcher = new IndexSearcher(reader); -101 TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); -102 searcher.search(q, collector); -103 ScoreDoc[] hits = collector.topDocs().scoreDocs; -104 -105 assertEquals("Did not find 1 document?", 1, hits.length); +57 Analyzer analyzer = new FieldAnalyzer(LuceneUtils.CURRENT_VERSION); +58 Directory index = new RAMDirectory(); +59 +60 String field1 = "product"; +61 String text1 = "springframework"; +62 +63 String field2 = "vendor"; +64 String text2 = "springsource"; +65 +66 createIndex(analyzer, index, field1, text1, field2, text2); +67 +68 //Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +69 String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)"; +70 +71 SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +72 SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +73 HashMap<String, Analyzer> map = new HashMap<String, Analyzer>(); +74 map.put(field1, searchAnalyzerProduct); +75 map.put(field2, searchAnalyzerVendor); +76 PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map); +77 QueryParser parser = new QueryParser(LuceneUtils.CURRENT_VERSION, field1, wrapper); +78 +79 Query q = parser.parse(querystr); +80 //System.out.println(q.toString()); +81 +82 int hitsPerPage = 10; +83 +84 IndexReader reader = DirectoryReader.open(index); +85 IndexSearcher searcher = new IndexSearcher(reader); +86 TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); +87 searcher.search(q, collector); +88 ScoreDoc[] hits = collector.topDocs().scoreDocs; +89 +90 assertEquals("Did not find 1 document?", 1, hits.length); +91 +92 searchAnalyzerProduct.clear(); //ensure we don't have anything left over from the previous search. +93 searchAnalyzerVendor.clear(); +94 querystr = "product:(Apache Struts) vendor:(Apache)"; +95 Query q2 = parser.parse(querystr); +96 //System.out.println(q2.toString()); +97 assertFalse("second parsing contains previousWord from the TokenPairConcatenatingFilter", q2.toString().contains("core")); +98 } +99 +100 private void createIndex(Analyzer analyzer, Directory index, String field1, String text1, String field2, String text2) throws IOException { +101 IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); +102 IndexWriter w = new IndexWriter(index, config); +103 addDoc(w, field1, text1, field2, text2); +104 w.close(); +105 } 106 -107 searchAnalyzerProduct.clear(); //ensure we don't have anything left over from the previous search. -108 searchAnalyzerVendor.clear(); -109 querystr = "product:(Apache Struts) vendor:(Apache)"; -110 Query q2 = parser.parse(querystr); -111 //System.out.println(q2.toString()); -112 assertFalse("second parsing contains previousWord from the TokenPairConcatenatingFilter", q2.toString().contains("core")); -113 } -114 -115 private void createIndex(Analyzer analyzer, Directory index, String field1, String text1, String field2, String text2) throws IOException { -116 IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); -117 IndexWriter w = new IndexWriter(index, config); -118 addDoc(w, field1, text1, field2, text2); -119 w.close(); -120 } -121 -122 private static void addDoc(IndexWriter w, String field1, String text1, String field2, String text2) throws IOException { -123 Document doc = new Document(); -124 doc.add(new TextField(field1, text1, Field.Store.YES)); -125 doc.add(new TextField(field2, text2, Field.Store.YES)); -126 w.addDocument(doc); -127 } -128 } +107 private static void addDoc(IndexWriter w, String field1, String text1, String field2, String text2) throws IOException { +108 Document doc = new Document(); +109 doc.add(new TextField(field1, text1, Field.Store.YES)); +110 doc.add(new TextField(field2, text2, Field.Store.YES)); +111 w.addDocument(doc); +112 } +113 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html b/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html index 068f8fbe4..5ebc9bc1e 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html @@ -31,74 +31,59 @@ 23 import org.junit.Before; 24 import org.junit.BeforeClass; 25 import org.junit.Test; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class LuceneUtilsTest { -32 -33 @BeforeClass -34 public static void setUpClass() throws Exception { -35 } -36 -37 @AfterClass -38 public static void tearDownClass() throws Exception { -39 } -40 -41 @Before -42 public void setUp() { -43 } -44 -45 @After -46 public void tearDown() { -47 } -48 -49 /** -50 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. -51 */ -52 @Test -53 public void testAppendEscapedLuceneQuery() { -54 StringBuilder buf = new StringBuilder(); -55 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; -56 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; -57 LuceneUtils.appendEscapedLuceneQuery(buf, text); -58 assertEquals(expResult, buf.toString()); -59 } -60 -61 /** -62 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. -63 */ -64 @Test -65 public void testAppendEscapedLuceneQuery_null() { -66 StringBuilder buf = new StringBuilder(); -67 CharSequence text = null; -68 LuceneUtils.appendEscapedLuceneQuery(buf, text); -69 assertEquals(0, buf.length()); -70 } -71 -72 /** -73 * Test of escapeLuceneQuery method, of class LuceneUtils. -74 */ -75 @Test -76 public void testEscapeLuceneQuery() { -77 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; -78 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; -79 String result = LuceneUtils.escapeLuceneQuery(text); -80 assertEquals(expResult, result); -81 } -82 -83 /** -84 * Test of escapeLuceneQuery method, of class LuceneUtils. -85 */ -86 @Test -87 public void testEscapeLuceneQuery_null() { -88 CharSequence text = null; -89 String expResult = null; -90 String result = LuceneUtils.escapeLuceneQuery(text); -91 assertEquals(expResult, result); -92 } -93 } +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public class LuceneUtilsTest extends BaseTest { +33 +34 /** +35 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. +36 */ +37 @Test +38 public void testAppendEscapedLuceneQuery() { +39 StringBuilder buf = new StringBuilder(); +40 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; +41 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; +42 LuceneUtils.appendEscapedLuceneQuery(buf, text); +43 assertEquals(expResult, buf.toString()); +44 } +45 +46 /** +47 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. +48 */ +49 @Test +50 public void testAppendEscapedLuceneQuery_null() { +51 StringBuilder buf = new StringBuilder(); +52 CharSequence text = null; +53 LuceneUtils.appendEscapedLuceneQuery(buf, text); +54 assertEquals(0, buf.length()); +55 } +56 +57 /** +58 * Test of escapeLuceneQuery method, of class LuceneUtils. +59 */ +60 @Test +61 public void testEscapeLuceneQuery() { +62 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; +63 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; +64 String result = LuceneUtils.escapeLuceneQuery(text); +65 assertEquals(expResult, result); +66 } +67 +68 /** +69 * Test of escapeLuceneQuery method, of class LuceneUtils. +70 */ +71 @Test +72 public void testEscapeLuceneQuery_null() { +73 CharSequence text = null; +74 String expResult = null; +75 String result = LuceneUtils.escapeLuceneQuery(text); +76 assertEquals(expResult, result); +77 } +78 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html b/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html index fe7104be7..f70d8c3ff 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html @@ -47,54 +47,46 @@ 39 */ 40 public class TokenPairConcatenatingFilterTest extends BaseTokenStreamTestCase { 41 -42 @BeforeClass -43 public static void setUpClass() { -44 } -45 -46 @AfterClass -47 public static void tearDownClass() { -48 } -49 -50 @Override -51 @Before -52 public void setUp() throws Exception { -53 super.setUp(); -54 } -55 -56 @Override -57 @After -58 public void tearDown() throws Exception { -59 super.tearDown(); -60 } -61 -62 /** -63 * test some examples -64 */ -65 public void testExamples() throws IOException { -66 Tokenizer wsTokenizer = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); -67 TokenStream filter = new TokenPairConcatenatingFilter(wsTokenizer); -68 assertTokenStreamContents(filter, -69 new String[]{"one", "onetwo", "two", "twothree", "three"}); -70 } +42 @Override +43 @Before +44 public void setUp() throws Exception { +45 super.setUp(); +46 } +47 +48 @Override +49 @After +50 public void tearDown() throws Exception { +51 super.tearDown(); +52 } +53 +54 /** +55 * test some examples +56 */ +57 public void testExamples() throws IOException { +58 Tokenizer wsTokenizer = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); +59 TokenStream filter = new TokenPairConcatenatingFilter(wsTokenizer); +60 assertTokenStreamContents(filter, +61 new String[]{"one", "onetwo", "two", "twothree", "three"}); +62 } +63 +64 /** +65 * Test of clear method, of class TokenPairConcatenatingFilter. +66 * +67 * @throws java.io.IOException +68 */ +69 @Test +70 public void testClear() throws IOException { 71 -72 /** -73 * Test of clear method, of class TokenPairConcatenatingFilter. -74 * -75 * @throws java.io.IOException -76 */ -77 @Test -78 public void testClear() throws IOException { -79 -80 TokenStream ts = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); -81 TokenPairConcatenatingFilter filter = new TokenPairConcatenatingFilter(ts); -82 assertTokenStreamContents(filter, new String[]{"one", "onetwo", "two", "twothree", "three"}); -83 -84 assertNotNull(filter.getPreviousWord()); -85 filter.clear(); -86 assertNull(filter.getPreviousWord()); -87 assertTrue(filter.getWords().isEmpty()); -88 } -89 } +72 TokenStream ts = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); +73 TokenPairConcatenatingFilter filter = new TokenPairConcatenatingFilter(ts); +74 assertTokenStreamContents(filter, new String[]{"one", "onetwo", "two", "twothree", "three"}); +75 +76 assertNotNull(filter.getPreviousWord()); +77 filter.clear(); +78 assertNull(filter.getPreviousWord()); +79 assertTrue(filter.getWords().isEmpty()); +80 } +81 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html b/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html index 1025f03ff..b8930b283 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html b/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html index 721806a02..8f16005d1 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html b/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html index ca9c6b030..fc03279f0 100644 --- a/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html b/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html index 4593064ce..30d1e78d6 100644 --- a/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html b/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html index 3ef7179b5..81bae1ab9 100644 --- a/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html b/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html index 18823ecf3..98a98d84c 100644 --- a/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.html index 579d7ed3c..e994487c5 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.html @@ -32,162 +32,183 @@ 24 import java.util.Map.Entry; 25 import java.util.Set; 26 import org.junit.Assert; -27 import static org.junit.Assert.assertTrue; -28 import org.junit.Test; -29 import org.owasp.dependencycheck.dependency.Vulnerability; -30 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -31 import org.owasp.dependencycheck.utils.DependencyVersion; -32 -33 /** -34 * -35 * @author Jeremy Long -36 */ -37 public class CveDBIntegrationTest extends BaseDBTestCase { -38 -39 /** -40 * Pretty useless tests of open, commit, and close methods, of class CveDB. -41 */ -42 @Test -43 public void testOpen() throws Exception { -44 CveDB instance = null; -45 try { -46 instance = new CveDB(); -47 instance.open(); -48 instance.commit(); -49 } finally { -50 if (instance != null) { -51 instance.close(); -52 } -53 } -54 } -55 -56 /** -57 * Test of getCPEs method, of class CveDB. -58 */ -59 @Test -60 public void testGetCPEs() throws Exception { -61 CveDB instance = null; -62 try { -63 instance = new CveDB(); -64 String vendor = "apache"; -65 String product = "struts"; -66 instance.open(); -67 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); -68 assertTrue(result.size() > 5); -69 } finally { -70 if (instance != null) { -71 instance.close(); -72 } -73 } -74 } -75 -76 /** -77 * Test of getVulnerabilities method, of class CveDB. -78 */ -79 @Test -80 public void testGetVulnerabilities() throws Exception { -81 String cpeStr = "cpe:/a:apache:struts:2.1.2"; -82 CveDB instance = null; -83 List<Vulnerability> results; +27 +28 import static org.junit.Assert.assertEquals; +29 import static org.junit.Assert.assertTrue; +30 import org.junit.Test; +31 import org.owasp.dependencycheck.dependency.Vulnerability; +32 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +33 import org.owasp.dependencycheck.utils.DependencyVersion; +34 +35 /** +36 * +37 * @author Jeremy Long +38 */ +39 public class CveDBIntegrationTest extends BaseDBTestCase { +40 +41 /** +42 * Pretty useless tests of open, commit, and close methods, of class CveDB. +43 */ +44 @Test +45 public void testOpen() throws Exception { +46 CveDB instance = null; +47 try { +48 instance = new CveDB(); +49 instance.open(); +50 instance.commit(); +51 } finally { +52 if (instance != null) { +53 instance.close(); +54 } +55 } +56 } +57 +58 /** +59 * Test of getCPEs method, of class CveDB. +60 */ +61 @Test +62 public void testGetCPEs() throws Exception { +63 CveDB instance = null; +64 try { +65 instance = new CveDB(); +66 String vendor = "apache"; +67 String product = "struts"; +68 instance.open(); +69 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); +70 assertTrue(result.size() > 5); +71 } finally { +72 if (instance != null) { +73 instance.close(); +74 } +75 } +76 } +77 +78 /** +79 * Test of getVulnerability method, of class CveDB. +80 */ +81 @Test +82 public void testgetVulnerability() throws Exception { +83 CveDB instance = null; 84 try { 85 instance = new CveDB(); 86 instance.open(); -87 results = instance.getVulnerabilities(cpeStr); -88 assertTrue(results.size() > 5); -89 cpeStr = "cpe:/a:jruby:jruby:1.6.3"; -90 results = instance.getVulnerabilities(cpeStr); -91 assertTrue(results.size() > 1); -92 -93 boolean found = false; -94 String expected = "CVE-2011-4838"; -95 for (Vulnerability v : results) { -96 if (expected.equals(v.getName())) { -97 found = true; -98 break; -99 } -100 } -101 assertTrue("Expected " + expected + ", but was not identified", found); -102 -103 found = false; -104 expected = "CVE-2012-5370"; -105 for (Vulnerability v : results) { -106 if (expected.equals(v.getName())) { -107 found = true; -108 break; -109 } -110 } -111 assertTrue("Expected " + expected + ", but was not identified", found); -112 -113 } finally { -114 if (instance != null) { -115 instance.close(); -116 } -117 } -118 } -119 -120 /** -121 * Test of getMatchingSoftware method, of class CveDB. -122 */ -123 @Test -124 public void testGetMatchingSoftware() throws Exception { -125 CveDB instance = null; -126 Map<String, Boolean> versions = new HashMap<String, Boolean>(); -127 DependencyVersion identifiedVersion = new DependencyVersion("1.0.1o"); -128 versions.put("cpe:/a:openssl:openssl:1.0.1e", Boolean.FALSE); -129 try { -130 instance = new CveDB(); -131 Entry<String, Boolean> results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); -132 Assert.assertNull(results); -133 versions.put("cpe:/a:openssl:openssl:1.0.1p", Boolean.FALSE); -134 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); -135 Assert.assertNull(results); -136 -137 versions.put("cpe:/a:openssl:openssl:1.0.1q", Boolean.TRUE); -138 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); -139 Assert.assertNotNull(results); -140 Assert.assertEquals("cpe:/a:openssl:openssl:1.0.1q", results.getKey()); -141 -142 versions.clear(); -143 -144 versions.put("cpe:/a:springsource:spring_framework:3.2.5", Boolean.FALSE); -145 versions.put("cpe:/a:springsource:spring_framework:3.2.6", Boolean.FALSE); -146 versions.put("cpe:/a:springsource:spring_framework:3.2.7", Boolean.TRUE); -147 -148 versions.put("cpe:/a:springsource:spring_framework:4.0.1", Boolean.TRUE); -149 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m1", Boolean.FALSE); -150 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m2", Boolean.FALSE); -151 versions.put("cpe:/a:springsource:spring_framework:4.0.0:rc1", Boolean.FALSE); -152 -153 identifiedVersion = new DependencyVersion("3.2.2"); -154 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -155 Assert.assertEquals("cpe:/a:springsource:spring_framework:3.2.7", results.getKey()); -156 Assert.assertTrue(results.getValue()); -157 identifiedVersion = new DependencyVersion("3.2.12"); -158 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -159 Assert.assertNull(results); -160 -161 identifiedVersion = new DependencyVersion("4.0.0"); -162 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -163 Assert.assertEquals("cpe:/a:springsource:spring_framework:4.0.1", results.getKey()); -164 Assert.assertTrue(results.getValue()); -165 identifiedVersion = new DependencyVersion("4.1.0"); -166 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -167 Assert.assertNull(results); +87 Vulnerability result = instance.getVulnerability("CVE-2014-0094"); +88 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()); +89 +90 } finally { +91 if (instance != null) { +92 instance.close(); +93 } +94 } +95 } +96 +97 /** +98 * Test of getVulnerabilities method, of class CveDB. +99 */ +100 @Test +101 public void testGetVulnerabilities() throws Exception { +102 String cpeStr = "cpe:/a:apache:struts:2.1.2"; +103 CveDB instance = null; +104 List<Vulnerability> results; +105 try { +106 instance = new CveDB(); +107 instance.open(); +108 results = instance.getVulnerabilities(cpeStr); +109 assertTrue(results.size() > 5); +110 cpeStr = "cpe:/a:jruby:jruby:1.6.3"; +111 results = instance.getVulnerabilities(cpeStr); +112 assertTrue(results.size() > 1); +113 +114 boolean found = false; +115 String expected = "CVE-2011-4838"; +116 for (Vulnerability v : results) { +117 if (expected.equals(v.getName())) { +118 found = true; +119 break; +120 } +121 } +122 assertTrue("Expected " + expected + ", but was not identified", found); +123 +124 found = false; +125 expected = "CVE-2012-5370"; +126 for (Vulnerability v : results) { +127 if (expected.equals(v.getName())) { +128 found = true; +129 break; +130 } +131 } +132 assertTrue("Expected " + expected + ", but was not identified", found); +133 +134 } finally { +135 if (instance != null) { +136 instance.close(); +137 } +138 } +139 } +140 +141 /** +142 * Test of getMatchingSoftware method, of class CveDB. +143 */ +144 @Test +145 public void testGetMatchingSoftware() throws Exception { +146 CveDB instance = null; +147 Map<String, Boolean> versions = new HashMap<String, Boolean>(); +148 DependencyVersion identifiedVersion = new DependencyVersion("1.0.1o"); +149 versions.put("cpe:/a:openssl:openssl:1.0.1e", Boolean.FALSE); +150 try { +151 instance = new CveDB(); +152 Entry<String, Boolean> results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); +153 Assert.assertNull(results); +154 versions.put("cpe:/a:openssl:openssl:1.0.1p", Boolean.FALSE); +155 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); +156 Assert.assertNull(results); +157 +158 versions.put("cpe:/a:openssl:openssl:1.0.1q", Boolean.TRUE); +159 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); +160 Assert.assertNotNull(results); +161 Assert.assertEquals("cpe:/a:openssl:openssl:1.0.1q", results.getKey()); +162 +163 versions.clear(); +164 +165 versions.put("cpe:/a:springsource:spring_framework:3.2.5", Boolean.FALSE); +166 versions.put("cpe:/a:springsource:spring_framework:3.2.6", Boolean.FALSE); +167 versions.put("cpe:/a:springsource:spring_framework:3.2.7", Boolean.TRUE); 168 -169 versions.clear(); -170 -171 versions.put("cpe:/a:jruby:jruby:-", Boolean.FALSE); -172 identifiedVersion = new DependencyVersion("1.6.3"); -173 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -174 Assert.assertNotNull(results); -175 } finally { -176 if (instance != null) { -177 instance.close(); -178 } -179 } -180 } +169 versions.put("cpe:/a:springsource:spring_framework:4.0.1", Boolean.TRUE); +170 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m1", Boolean.FALSE); +171 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m2", Boolean.FALSE); +172 versions.put("cpe:/a:springsource:spring_framework:4.0.0:rc1", Boolean.FALSE); +173 +174 identifiedVersion = new DependencyVersion("3.2.2"); +175 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +176 Assert.assertEquals("cpe:/a:springsource:spring_framework:3.2.7", results.getKey()); +177 Assert.assertTrue(results.getValue()); +178 identifiedVersion = new DependencyVersion("3.2.12"); +179 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +180 Assert.assertNull(results); 181 -182 } +182 identifiedVersion = new DependencyVersion("4.0.0"); +183 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +184 Assert.assertEquals("cpe:/a:springsource:spring_framework:4.0.1", results.getKey()); +185 Assert.assertTrue(results.getValue()); +186 identifiedVersion = new DependencyVersion("4.1.0"); +187 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +188 Assert.assertNull(results); +189 +190 versions.clear(); +191 +192 versions.put("cpe:/a:jruby:jruby:-", Boolean.FALSE); +193 identifiedVersion = new DependencyVersion("1.6.3"); +194 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +195 Assert.assertNotNull(results); +196 } finally { +197 if (instance != null) { +198 instance.close(); +199 } +200 } +201 } +202 +203 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html index 1dabd5f74..e861d3cbf 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html @@ -33,88 +33,71 @@ 25 import org.junit.Before; 26 import org.junit.BeforeClass; 27 import org.junit.Test; -28 import org.owasp.dependencycheck.dependency.Vulnerability; -29 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -30 import org.owasp.dependencycheck.utils.Settings; -31 -32 /** -33 * -34 * @author Jeremy Long -35 */ -36 public class CveDBMySQLTest { -37 -38 @BeforeClass -39 public static void setUpClass() { -40 Settings.initialize(); -41 } -42 -43 @AfterClass -44 public static void tearDownClass() { -45 Settings.cleanup(); -46 } -47 -48 @Before -49 public void setUp() throws Exception { -50 } -51 -52 @After -53 public void tearDown() throws Exception { -54 } -55 -56 /** -57 * Pretty useless tests of open, commit, and close methods, of class CveDB. -58 */ -59 @Test -60 public void testOpen() throws DatabaseException { -61 try { -62 CveDB instance = new CveDB(); +28 import org.owasp.dependencycheck.BaseTest; +29 import org.owasp.dependencycheck.dependency.Vulnerability; +30 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +31 import org.owasp.dependencycheck.utils.Settings; +32 +33 /** +34 * +35 * @author Jeremy Long +36 */ +37 public class CveDBMySQLTest extends BaseTest { +38 +39 /** +40 * Pretty useless tests of open, commit, and close methods, of class CveDB. +41 */ +42 @Test +43 public void testOpen() throws DatabaseException { +44 try { +45 CveDB instance = new CveDB(); +46 instance.open(); +47 instance.close(); +48 } catch (DatabaseException ex) { +49 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"); +50 throw ex; +51 } +52 } +53 +54 /** +55 * Test of getCPEs method, of class CveDB. +56 */ +57 @Test +58 public void testGetCPEs() throws Exception { +59 CveDB instance = new CveDB(); +60 try { +61 String vendor = "apache"; +62 String product = "struts"; 63 instance.open(); -64 instance.close(); -65 } catch (DatabaseException ex) { -66 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"); -67 throw ex; -68 } -69 } -70 -71 /** -72 * Test of getCPEs method, of class CveDB. -73 */ -74 @Test -75 public void testGetCPEs() throws Exception { -76 CveDB instance = new CveDB(); -77 try { -78 String vendor = "apache"; -79 String product = "struts"; -80 instance.open(); -81 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); -82 assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); -83 } catch (Exception ex) { -84 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); -85 throw ex; -86 } finally { -87 instance.close(); -88 } -89 } -90 -91 /** -92 * Test of getVulnerabilities method, of class CveDB. -93 */ -94 @Test -95 public void testGetVulnerabilities() throws Exception { -96 String cpeStr = "cpe:/a:apache:struts:2.1.2"; -97 CveDB instance = new CveDB(); -98 try { -99 instance.open(); -100 List<Vulnerability> result = instance.getVulnerabilities(cpeStr); -101 assertTrue(result.size() > 5); -102 } catch (Exception ex) { -103 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); -104 throw ex; -105 } finally { -106 instance.close(); -107 } -108 } -109 } +64 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); +65 assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); +66 } catch (Exception ex) { +67 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); +68 throw ex; +69 } finally { +70 instance.close(); +71 } +72 } +73 +74 /** +75 * Test of getVulnerabilities method, of class CveDB. +76 */ +77 @Test +78 public void testGetVulnerabilities() throws Exception { +79 String cpeStr = "cpe:/a:apache:struts:2.1.2"; +80 CveDB instance = new CveDB(); +81 try { +82 instance.open(); +83 List<Vulnerability> result = instance.getVulnerabilities(cpeStr); +84 assertTrue(result.size() > 5); +85 } catch (Exception ex) { +86 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); +87 throw ex; +88 } finally { +89 instance.close(); +90 } +91 } +92 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html index 53a1a956b..ddf2c22d1 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html @@ -41,127 +41,109 @@ 33 * 34 * @author Jeremy Long 35 */ -36 public class DriverLoaderTest { +36 public class DriverLoaderTest extends BaseTest { 37 -38 public DriverLoaderTest() { -39 } -40 -41 @BeforeClass -42 public static void setUpClass() { -43 } -44 -45 @AfterClass -46 public static void tearDownClass() { -47 } -48 -49 @Before -50 public void setUp() { -51 } -52 -53 @After -54 public void tearDown() { -55 } -56 -57 /** -58 * Test of load method, of class DriverLoader. -59 */ -60 @Test -61 public void testLoad_String() throws Exception { -62 String className = "org.h2.Driver"; -63 Driver d = null; -64 try { -65 d = DriverLoader.load(className); -66 } finally { -67 if (d != null) { -68 DriverManager.deregisterDriver(d); -69 } -70 } -71 } -72 -73 /** -74 * Test of load method, of class DriverLoader; expecting an exception due to a bad driver class name. -75 */ -76 @Test(expected = DriverLoadException.class) -77 public void testLoad_String_ex() throws Exception { -78 String className = "bad.Driver"; -79 Driver d = DriverLoader.load(className); -80 } -81 -82 /** -83 * Test of load method, of class DriverLoader. -84 */ -85 @Test -86 public void testLoad_String_String() throws Exception { -87 String className = "com.mysql.jdbc.Driver"; -88 //we know this is in target/test-classes -89 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -90 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -91 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); -92 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); -93 -94 Driver d = null; -95 try { -96 d = DriverLoader.load(className, driver.getAbsolutePath()); -97 d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck"); -98 assertNotNull(d); -99 } finally { -100 if (d != null) { -101 DriverManager.deregisterDriver(d); -102 } -103 } -104 } -105 -106 /** -107 * Test of load method, of class DriverLoader. -108 */ -109 @Test -110 public void testLoad_String_String_multiple_paths() throws Exception { -111 final String className = "com.mysql.jdbc.Driver"; -112 //we know this is in target/test-classes -113 //final File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -114 final File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -115 final File dir1 = new File(testClassPath, "../../src/test/"); -116 final File dir2 = new File(testClassPath, "../../src/test/resources/"); -117 final String paths = String.format("%s" + File.pathSeparator + "%s", dir1.getAbsolutePath(), dir2.getAbsolutePath()); -118 -119 Driver d = null; -120 try { -121 d = DriverLoader.load(className, paths); -122 } finally { -123 if (d != null) { -124 DriverManager.deregisterDriver(d); -125 } -126 } -127 } -128 -129 /** -130 * Test of load method, of class DriverLoader with an incorrect class name. -131 */ -132 @Test(expected = DriverLoadException.class) -133 public void testLoad_String_String_badClassName() throws Exception { -134 String className = "com.mybad.jdbc.Driver"; -135 //we know this is in target/test-classes -136 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -137 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -138 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); -139 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); -140 -141 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); -142 } -143 -144 /** -145 * Test of load method, of class DriverLoader with an incorrect class path. -146 */ -147 @Test(expected = DriverLoadException.class) -148 public void testLoad_String_String_badPath() throws Exception { -149 String className = "com.mysql.jdbc.Driver"; -150 //we know this is in target/test-classes -151 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -152 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -153 File driver = new File(testClassPath, "../../src/test/bad/mysql-connector-java-5.1.27-bin.jar"); -154 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); -155 } -156 } +38 /** +39 * Test of load method, of class DriverLoader. +40 */ +41 @Test +42 public void testLoad_String() throws Exception { +43 String className = "org.h2.Driver"; +44 Driver d = null; +45 try { +46 d = DriverLoader.load(className); +47 } finally { +48 if (d != null) { +49 DriverManager.deregisterDriver(d); +50 } +51 } +52 } +53 +54 /** +55 * Test of load method, of class DriverLoader; expecting an exception due to +56 * a bad driver class name. +57 */ +58 @Test(expected = DriverLoadException.class) +59 public void testLoad_String_ex() throws Exception { +60 String className = "bad.Driver"; +61 Driver d = DriverLoader.load(className); +62 } +63 +64 /** +65 * Test of load method, of class DriverLoader. +66 */ +67 @Test +68 public void testLoad_String_String() throws Exception { +69 String className = "com.mysql.jdbc.Driver"; +70 //we know this is in target/test-classes +71 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +72 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +73 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); +74 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); +75 +76 Driver d = null; +77 try { +78 d = DriverLoader.load(className, driver.getAbsolutePath()); +79 d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck"); +80 assertNotNull(d); +81 } finally { +82 if (d != null) { +83 DriverManager.deregisterDriver(d); +84 } +85 } +86 } +87 +88 /** +89 * Test of load method, of class DriverLoader. +90 */ +91 @Test +92 public void testLoad_String_String_multiple_paths() throws Exception { +93 final String className = "com.mysql.jdbc.Driver"; +94 //we know this is in target/test-classes +95 //final File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +96 final File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +97 final File dir1 = new File(testClassPath, "../../src/test/"); +98 final File dir2 = new File(testClassPath, "../../src/test/resources/"); +99 final String paths = String.format("%s" + File.pathSeparator + "%s", dir1.getAbsolutePath(), dir2.getAbsolutePath()); +100 +101 Driver d = null; +102 try { +103 d = DriverLoader.load(className, paths); +104 } finally { +105 if (d != null) { +106 DriverManager.deregisterDriver(d); +107 } +108 } +109 } +110 +111 /** +112 * Test of load method, of class DriverLoader with an incorrect class name. +113 */ +114 @Test(expected = DriverLoadException.class) +115 public void testLoad_String_String_badClassName() throws Exception { +116 String className = "com.mybad.jdbc.Driver"; +117 //we know this is in target/test-classes +118 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +119 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +120 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); +121 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); +122 +123 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); +124 } +125 +126 /** +127 * Test of load method, of class DriverLoader with an incorrect class path. +128 */ +129 @Test(expected = DriverLoadException.class) +130 public void testLoad_String_String_badPath() throws Exception { +131 String className = "com.mysql.jdbc.Driver"; +132 //we know this is in target/test-classes +133 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +134 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +135 File driver = new File(testClassPath, "../../src/test/bad/mysql-connector-java-5.1.27-bin.jar"); +136 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); +137 } +138 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html index b4c0d96e7..b55b61c9f 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html index 2f60df2cc..f54a7bc28 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html b/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html index 3a36bbbdb..8881857a7 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html +++ b/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html @@ -44,41 +44,22 @@ 36 * 37 * @author Jeremy Long 38 */ -39 public class NvdCve_1_2_HandlerTest { +39 public class NvdCve_1_2_HandlerTest extends BaseTest { 40 -41 public NvdCve_1_2_HandlerTest() { -42 } -43 -44 @BeforeClass -45 public static void setUpClass() throws Exception { -46 } -47 -48 @AfterClass -49 public static void tearDownClass() throws Exception { -50 } -51 -52 @Before -53 public void setUp() { -54 } -55 -56 @After -57 public void tearDown() { -58 } -59 -60 @Test -61 public void testParse() throws Exception { -62 SAXParserFactory factory = SAXParserFactory.newInstance(); -63 SAXParser saxParser = factory.newSAXParser(); -64 -65 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2012.xml").getPath()); -66 File file = BaseTest.getResourceAsFile(this, "nvdcve-2012.xml"); -67 -68 NvdCve12Handler instance = new NvdCve12Handler(); -69 saxParser.parse(file, instance); -70 Map<String, List<VulnerableSoftware>> results = instance.getVulnerabilities(); -71 assertTrue("No vulnerable software identified with a previous version in 2012 CVE 1.2?", !results.isEmpty()); -72 } -73 } +41 @Test +42 public void testParse() throws Exception { +43 SAXParserFactory factory = SAXParserFactory.newInstance(); +44 SAXParser saxParser = factory.newSAXParser(); +45 +46 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2012.xml").getPath()); +47 File file = BaseTest.getResourceAsFile(this, "nvdcve-2012.xml"); +48 +49 NvdCve12Handler instance = new NvdCve12Handler(); +50 saxParser.parse(file, instance); +51 Map<String, List<VulnerableSoftware>> results = instance.getVulnerabilities(); +52 assertTrue("No vulnerable software identified with a previous version in 2012 CVE 1.2?", !results.isEmpty()); +53 } +54 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html b/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html index 694c8c1d4..f892447bd 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html +++ b/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html @@ -27,64 +27,78 @@ 19 20 import org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler; 21 import java.io.File; -22 import javax.xml.parsers.SAXParser; -23 import javax.xml.parsers.SAXParserFactory; -24 import org.junit.After; -25 import org.junit.AfterClass; -26 import static org.junit.Assert.assertTrue; -27 import org.junit.Before; -28 import org.junit.BeforeClass; -29 import org.junit.Test; -30 import org.owasp.dependencycheck.BaseTest; -31 -32 /** -33 * -34 * @author Jeremy Long -35 */ -36 public class NvdCve_2_0_HandlerTest { -37 -38 public NvdCve_2_0_HandlerTest() { -39 } +22 import java.util.List; +23 import java.util.Map; +24 import javax.xml.parsers.SAXParser; +25 import javax.xml.parsers.SAXParserFactory; +26 import org.junit.After; +27 import org.junit.AfterClass; +28 import static org.junit.Assert.assertTrue; +29 import org.junit.Before; +30 import org.junit.BeforeClass; +31 import org.junit.Test; +32 import org.owasp.dependencycheck.BaseTest; +33 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +34 +35 /** +36 * +37 * @author Jeremy Long +38 */ +39 public class NvdCve_2_0_HandlerTest extends BaseTest { 40 -41 @BeforeClass -42 public static void setUpClass() throws Exception { -43 } -44 -45 @AfterClass -46 public static void tearDownClass() throws Exception { -47 } -48 -49 @Before -50 public void setUp() { -51 } +41 @Test +42 public void testParse() { +43 Throwable results = null; +44 try { +45 SAXParserFactory factory = SAXParserFactory.newInstance(); +46 SAXParser saxParser = factory.newSAXParser(); +47 +48 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); +49 File file = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2012.xml"); +50 +51 NvdCve20Handler instance = new NvdCve20Handler(); 52 -53 @After -54 public void tearDown() { -55 } -56 -57 @Test -58 public void testParse() { -59 Throwable results = null; -60 try { -61 SAXParserFactory factory = SAXParserFactory.newInstance(); -62 SAXParser saxParser = factory.newSAXParser(); +53 saxParser.parse(file, instance); +54 } catch (Throwable ex) { +55 ex.printStackTrace(); +56 results = ex; +57 } +58 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); +59 if (results != null) { +60 System.err.println(results); +61 } +62 } 63 -64 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); -65 File file = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2012.xml"); -66 -67 NvdCve20Handler instance = new NvdCve20Handler(); -68 -69 saxParser.parse(file, instance); -70 } catch (Throwable ex) { -71 results = ex; -72 } -73 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); -74 if (results != null) { -75 System.err.println(results); -76 } -77 -78 } -79 } +64 @Test +65 public void testParserWithPreviousVersion() { +66 Throwable results = null; +67 try { +68 SAXParserFactory factory = SAXParserFactory.newInstance(); +69 SAXParser saxParser = factory.newSAXParser(); +70 +71 File file12 = BaseTest.getResourceAsFile(this, "cve-1.2-2008_4411.xml"); +72 +73 final NvdCve12Handler cve12Handler = new NvdCve12Handler(); +74 saxParser.parse(file12, cve12Handler); +75 final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities(); +76 +77 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); +78 File file20 = BaseTest.getResourceAsFile(this, "cve-2.0-2008_4411.xml"); +79 +80 NvdCve20Handler instance = new NvdCve20Handler(); +81 instance.setPrevVersionVulnMap(prevVersionVulnMap); +82 saxParser.parse(file20, instance); +83 +84 assertTrue(instance.getTotalNumberOfEntries()==1); +85 } catch (Throwable ex) { +86 results = ex; +87 } +88 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); +89 if (results != null) { +90 System.err.println(results); +91 } +92 } +93 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html b/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html index 7a7ba872b..789426227 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html index ad304edef..7d67721bb 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/xref-test/org/owasp/dependencycheck/data/update/package-frame.html b/xref-test/org/owasp/dependencycheck/data/update/package-frame.html index c5760bcbf..475a43b19 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/update/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update diff --git a/xref-test/org/owasp/dependencycheck/data/update/package-summary.html b/xref-test/org/owasp/dependencycheck/data/update/package-summary.html index 0aedc640c..c9cc469b5 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/update/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update diff --git a/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html b/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html index 57553ab8c..5016a0f4e 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html +++ b/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html @@ -43,282 +43,263 @@ 35 * 36 * @author Jeremy Long 37 */ -38 public class DependencyTest { +38 public class DependencyTest extends BaseTest { 39 -40 public DependencyTest() { -41 } -42 -43 @BeforeClass -44 public static void setUpClass() throws Exception { -45 } -46 -47 @AfterClass -48 public static void tearDownClass() throws Exception { -49 } -50 -51 @Before -52 public void setUp() { -53 } -54 -55 @After -56 public void tearDown() { -57 } -58 -59 /** -60 * Test of getFileName method, of class Dependency. -61 */ -62 @Test -63 public void testGetFileName() { -64 Dependency instance = new Dependency(); -65 String expResult = "filename"; -66 instance.setFileName(expResult); -67 String result = instance.getFileName(); -68 assertEquals(expResult, result); -69 } -70 -71 /** -72 * Test of setFileName method, of class Dependency. -73 */ -74 @Test -75 public void testSetFileName() { -76 String fileName = "file.tar"; -77 Dependency instance = new Dependency(); -78 instance.setFileName(fileName); -79 assertEquals(fileName, instance.getFileName()); -80 } -81 -82 /** -83 * Test of setActualFilePath method, of class Dependency. -84 */ -85 @Test -86 public void testSetActualFilePath() { -87 String actualFilePath = "file.tar"; -88 Dependency instance = new Dependency(); -89 instance.setSha1sum("non-null value"); -90 instance.setActualFilePath(actualFilePath); -91 assertEquals(actualFilePath, instance.getActualFilePath()); -92 } -93 -94 /** -95 * Test of getActualFilePath method, of class Dependency. -96 */ -97 @Test -98 public void testGetActualFilePath() { -99 Dependency instance = new Dependency(); -100 String expResult = "file.tar"; -101 instance.setSha1sum("non-null value"); -102 instance.setActualFilePath(expResult); -103 String result = instance.getActualFilePath(); -104 assertEquals(expResult, result); -105 } -106 -107 /** -108 * Test of setFilePath method, of class Dependency. -109 */ -110 @Test -111 public void testSetFilePath() { -112 String filePath = "file.tar"; -113 Dependency instance = new Dependency(); -114 instance.setFilePath(filePath); -115 assertEquals(filePath, instance.getFilePath()); -116 } -117 -118 /** -119 * Test of getFilePath method, of class Dependency. -120 */ -121 @Test -122 public void testGetFilePath() { -123 Dependency instance = new Dependency(); -124 String expResult = "file.tar"; -125 instance.setFilePath(expResult); -126 String result = instance.getFilePath(); -127 assertEquals(expResult, result); -128 } -129 -130 /** -131 * Test of getMd5sum method, of class Dependency. -132 */ -133 @Test -134 public void testGetMd5sum() { -135 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -136 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +40 /** +41 * Test of getFileName method, of class Dependency. +42 */ +43 @Test +44 public void testGetFileName() { +45 Dependency instance = new Dependency(); +46 String expResult = "filename"; +47 instance.setFileName(expResult); +48 String result = instance.getFileName(); +49 assertEquals(expResult, result); +50 } +51 +52 /** +53 * Test of setFileName method, of class Dependency. +54 */ +55 @Test +56 public void testSetFileName() { +57 String fileName = "file.tar"; +58 Dependency instance = new Dependency(); +59 instance.setFileName(fileName); +60 assertEquals(fileName, instance.getFileName()); +61 } +62 +63 /** +64 * Test of setActualFilePath method, of class Dependency. +65 */ +66 @Test +67 public void testSetActualFilePath() { +68 String actualFilePath = "file.tar"; +69 Dependency instance = new Dependency(); +70 instance.setSha1sum("non-null value"); +71 instance.setActualFilePath(actualFilePath); +72 assertEquals(actualFilePath, instance.getActualFilePath()); +73 } +74 +75 /** +76 * Test of getActualFilePath method, of class Dependency. +77 */ +78 @Test +79 public void testGetActualFilePath() { +80 Dependency instance = new Dependency(); +81 String expResult = "file.tar"; +82 instance.setSha1sum("non-null value"); +83 instance.setActualFilePath(expResult); +84 String result = instance.getActualFilePath(); +85 assertEquals(expResult, result); +86 } +87 +88 /** +89 * Test of setFilePath method, of class Dependency. +90 */ +91 @Test +92 public void testSetFilePath() { +93 String filePath = "file.tar"; +94 Dependency instance = new Dependency(); +95 instance.setFilePath(filePath); +96 assertEquals(filePath, instance.getFilePath()); +97 } +98 +99 /** +100 * Test of getFilePath method, of class Dependency. +101 */ +102 @Test +103 public void testGetFilePath() { +104 Dependency instance = new Dependency(); +105 String expResult = "file.tar"; +106 instance.setFilePath(expResult); +107 String result = instance.getFilePath(); +108 assertEquals(expResult, result); +109 } +110 +111 /** +112 * Test of getMd5sum method, of class Dependency. +113 */ +114 @Test +115 public void testGetMd5sum() { +116 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +117 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +118 +119 Dependency instance = new Dependency(file); +120 //assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); +121 //String expResult = "C30B57142E1CCBC1EFD5CD15F307358F"; +122 String expResult = "c30b57142e1ccbc1efd5cd15f307358f"; +123 String result = instance.getMd5sum(); +124 assertEquals(expResult, result); +125 } +126 +127 /** +128 * Test of setMd5sum method, of class Dependency. +129 */ +130 @Test +131 public void testSetMd5sum() { +132 String md5sum = "test"; +133 Dependency instance = new Dependency(); +134 instance.setMd5sum(md5sum); +135 assertEquals(md5sum, instance.getMd5sum()); +136 } 137 -138 Dependency instance = new Dependency(file); -139 //assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); -140 //String expResult = "C30B57142E1CCBC1EFD5CD15F307358F"; -141 String expResult = "c30b57142e1ccbc1efd5cd15f307358f"; -142 String result = instance.getMd5sum(); -143 assertEquals(expResult, result); -144 } -145 -146 /** -147 * Test of setMd5sum method, of class Dependency. -148 */ -149 @Test -150 public void testSetMd5sum() { -151 String md5sum = "test"; -152 Dependency instance = new Dependency(); -153 instance.setMd5sum(md5sum); -154 assertEquals(md5sum, instance.getMd5sum()); -155 } -156 -157 /** -158 * Test of getSha1sum method, of class Dependency. -159 */ -160 @Test -161 public void testGetSha1sum() { -162 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -163 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -164 Dependency instance = new Dependency(file); -165 //String expResult = "89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B"; -166 String expResult = "89ce9e36aa9a9e03f1450936d2f4f8dd0f961f8b"; -167 String result = instance.getSha1sum(); -168 assertEquals(expResult, result); -169 } +138 /** +139 * Test of getSha1sum method, of class Dependency. +140 */ +141 @Test +142 public void testGetSha1sum() { +143 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +144 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +145 Dependency instance = new Dependency(file); +146 //String expResult = "89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B"; +147 String expResult = "89ce9e36aa9a9e03f1450936d2f4f8dd0f961f8b"; +148 String result = instance.getSha1sum(); +149 assertEquals(expResult, result); +150 } +151 +152 /** +153 * Test of setSha1sum method, of class Dependency. +154 */ +155 @Test +156 public void testSetSha1sum() { +157 String sha1sum = "test"; +158 Dependency instance = new Dependency(); +159 instance.setSha1sum(sha1sum); +160 assertEquals(sha1sum, instance.getSha1sum()); +161 } +162 +163 /** +164 * Test of getIdentifiers method, of class Dependency. +165 */ +166 @Test +167 public void testGetIdentifiers() { +168 Dependency instance = new Dependency(); +169 Set<Identifier> result = instance.getIdentifiers(); 170 -171 /** -172 * Test of setSha1sum method, of class Dependency. -173 */ -174 @Test -175 public void testSetSha1sum() { -176 String sha1sum = "test"; -177 Dependency instance = new Dependency(); -178 instance.setSha1sum(sha1sum); -179 assertEquals(sha1sum, instance.getSha1sum()); -180 } -181 -182 /** -183 * Test of getIdentifiers method, of class Dependency. -184 */ -185 @Test -186 public void testGetIdentifiers() { -187 Dependency instance = new Dependency(); -188 Set<Identifier> result = instance.getIdentifiers(); -189 -190 assertTrue(true); //this is just a getter setter pair. -191 } -192 -193 /** -194 * Test of setIdentifiers method, of class Dependency. -195 */ -196 @Test -197 public void testSetIdentifiers() { -198 Set<Identifier> identifiers = null; -199 Dependency instance = new Dependency(); -200 instance.setIdentifiers(identifiers); -201 assertTrue(true); //this is just a getter setter pair. -202 } -203 -204 /** -205 * Test of addIdentifier method, of class Dependency. -206 */ -207 @Test -208 public void testAddIdentifier() { -209 String type = "cpe"; -210 String value = "cpe:/a:apache:struts:2.1.2"; -211 String url = "http://somewhere"; -212 Identifier expResult = new Identifier(type, value, url); -213 -214 Dependency instance = new Dependency(); -215 instance.addIdentifier(type, value, url); -216 assertEquals(1, instance.getIdentifiers().size()); -217 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); -218 } +171 assertTrue(true); //this is just a getter setter pair. +172 } +173 +174 /** +175 * Test of setIdentifiers method, of class Dependency. +176 */ +177 @Test +178 public void testSetIdentifiers() { +179 Set<Identifier> identifiers = null; +180 Dependency instance = new Dependency(); +181 instance.setIdentifiers(identifiers); +182 assertTrue(true); //this is just a getter setter pair. +183 } +184 +185 /** +186 * Test of addIdentifier method, of class Dependency. +187 */ +188 @Test +189 public void testAddIdentifier() { +190 String type = "cpe"; +191 String value = "cpe:/a:apache:struts:2.1.2"; +192 String url = "http://somewhere"; +193 Identifier expResult = new Identifier(type, value, url); +194 +195 Dependency instance = new Dependency(); +196 instance.addIdentifier(type, value, url); +197 assertEquals(1, instance.getIdentifiers().size()); +198 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); +199 } +200 +201 /** +202 * Test of getEvidence method, of class Dependency. +203 */ +204 @Test +205 public void testGetEvidence() { +206 Dependency instance = new Dependency(); +207 EvidenceCollection expResult = null; +208 EvidenceCollection result = instance.getEvidence(); +209 assertTrue(true); //this is just a getter setter pair. +210 } +211 +212 /** +213 * Test of getEvidenceUsed method, of class Dependency. +214 */ +215 @Test +216 public void testGetEvidenceUsed() { +217 Dependency instance = new Dependency(); +218 String expResult = "used"; 219 -220 /** -221 * Test of getEvidence method, of class Dependency. -222 */ -223 @Test -224 public void testGetEvidence() { -225 Dependency instance = new Dependency(); -226 EvidenceCollection expResult = null; -227 EvidenceCollection result = instance.getEvidence(); -228 assertTrue(true); //this is just a getter setter pair. -229 } -230 -231 /** -232 * Test of getEvidenceUsed method, of class Dependency. -233 */ -234 @Test -235 public void testGetEvidenceUsed() { -236 Dependency instance = new Dependency(); -237 String expResult = "used"; -238 -239 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); -240 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); -241 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { -242 String use = e.getValue(); -243 } -244 -245 EvidenceCollection result = instance.getEvidenceUsed(); -246 -247 assertEquals(1, result.size()); -248 assertTrue(result.containsUsedString(expResult)); -249 } -250 -251 /** -252 * Test of getVendorEvidence method, of class Dependency. -253 */ -254 @Test -255 public void testGetVendorEvidence() { -256 Dependency instance = new Dependency(); -257 EvidenceCollection expResult = null; -258 EvidenceCollection result = instance.getVendorEvidence(); -259 assertTrue(true); //this is just a getter setter pair. -260 } -261 -262 /** -263 * Test of getProductEvidence method, of class Dependency. -264 */ -265 @Test -266 public void testGetProductEvidence() { -267 Dependency instance = new Dependency(); -268 EvidenceCollection expResult = null; -269 EvidenceCollection result = instance.getProductEvidence(); -270 assertTrue(true); //this is just a getter setter pair. -271 } -272 -273 /** -274 * Test of getVersionEvidence method, of class Dependency. -275 */ -276 @Test -277 public void testGetVersionEvidence() { -278 Dependency instance = new Dependency(); -279 EvidenceCollection expResult = null; -280 EvidenceCollection result = instance.getVersionEvidence(); -281 assertTrue(true); //this is just a getter setter pair. -282 } -283 -284 /** -285 * Test of addAsEvidence method, of class Dependency. -286 */ -287 @Test -288 public void testAddAsEvidence() { -289 Dependency instance = new Dependency(); -290 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); -291 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -292 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); -293 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -294 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -295 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -296 assertFalse(instance.getIdentifiers().isEmpty()); -297 } -298 -299 /** -300 * Test of addAsEvidence method, of class Dependency. -301 */ -302 @Test -303 public void testAddAsEvidenceWithEmptyArtefact() { -304 Dependency instance = new Dependency(); -305 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); -306 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -307 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); -308 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -309 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -310 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -311 assertTrue(instance.getIdentifiers().isEmpty()); -312 } -313 } +220 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); +221 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); +222 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { +223 String use = e.getValue(); +224 } +225 +226 EvidenceCollection result = instance.getEvidenceUsed(); +227 +228 assertEquals(1, result.size()); +229 assertTrue(result.containsUsedString(expResult)); +230 } +231 +232 /** +233 * Test of getVendorEvidence method, of class Dependency. +234 */ +235 @Test +236 public void testGetVendorEvidence() { +237 Dependency instance = new Dependency(); +238 EvidenceCollection expResult = null; +239 EvidenceCollection result = instance.getVendorEvidence(); +240 assertTrue(true); //this is just a getter setter pair. +241 } +242 +243 /** +244 * Test of getProductEvidence method, of class Dependency. +245 */ +246 @Test +247 public void testGetProductEvidence() { +248 Dependency instance = new Dependency(); +249 EvidenceCollection expResult = null; +250 EvidenceCollection result = instance.getProductEvidence(); +251 assertTrue(true); //this is just a getter setter pair. +252 } +253 +254 /** +255 * Test of getVersionEvidence method, of class Dependency. +256 */ +257 @Test +258 public void testGetVersionEvidence() { +259 Dependency instance = new Dependency(); +260 EvidenceCollection expResult = null; +261 EvidenceCollection result = instance.getVersionEvidence(); +262 assertTrue(true); //this is just a getter setter pair. +263 } +264 +265 /** +266 * Test of addAsEvidence method, of class Dependency. +267 */ +268 @Test +269 public void testAddAsEvidence() { +270 Dependency instance = new Dependency(); +271 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); +272 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +273 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); +274 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +275 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +276 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +277 assertFalse(instance.getIdentifiers().isEmpty()); +278 } +279 +280 /** +281 * Test of addAsEvidence method, of class Dependency. +282 */ +283 @Test +284 public void testAddAsEvidenceWithEmptyArtefact() { +285 Dependency instance = new Dependency(); +286 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); +287 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +288 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); +289 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +290 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +291 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +292 assertTrue(instance.getIdentifiers().isEmpty()); +293 } +294 }
      diff --git a/xref-test/org/owasp/dependencycheck/dependency/EvidenceTest.html b/xref-test/org/owasp/dependencycheck/dependency/EvidenceTest.html index c5b4d558f..92e63b507 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/EvidenceTest.html +++ b/xref-test/org/owasp/dependencycheck/dependency/EvidenceTest.html @@ -28,98 +28,99 @@ 20 import org.junit.Test; 21 import static org.junit.Assert.*; 22 import static org.hamcrest.CoreMatchers.*; -23 -24 /** -25 * -26 * @author Jeremy Long -27 */ -28 public class EvidenceTest { -29 -30 /** -31 * Test of equals method, of class Evidence. -32 */ -33 @Test -34 public void testEquals() { -35 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); -36 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); -37 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); -38 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); -39 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); -40 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); -41 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); -42 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); -43 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -44 -45 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -46 assertFalse(instance.equals(that0)); -47 assertFalse(instance.equals(that1)); -48 assertFalse(instance.equals(that2)); -49 assertFalse(instance.equals(that3)); -50 assertFalse(instance.equals(that4)); -51 assertFalse(instance.equals(that5)); -52 assertFalse(instance.equals(that6)); -53 assertFalse(instance.equals(that7)); -54 assertTrue(instance.equals(that8)); -55 } -56 -57 @Test -58 public void testHashcodeContract() throws Exception { -59 final Evidence titleCase = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -60 final Evidence lowerCase = new Evidence("manifest", "implementation-title", "spring framework", Confidence.HIGH); -61 assertThat(titleCase, is(equalTo(lowerCase))); -62 assertThat(titleCase.hashCode(), is(equalTo(lowerCase.hashCode()))); -63 } -64 -65 /** -66 * Test of compareTo method, of class Evidence. -67 */ -68 @Test -69 public void testCompareTo() { -70 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); -71 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); -72 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); -73 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); -74 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); -75 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); -76 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); -77 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); -78 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -79 -80 Evidence that9 = new Evidence("manifest", "implementation-title", "zippy", Confidence.HIGH); -81 -82 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -83 -84 int result = instance.compareTo(that0); -85 assertTrue(result > 0); -86 -87 result = instance.compareTo(that1); -88 assertTrue(result > 0); -89 -90 result = instance.compareTo(that2); -91 assertTrue(result > 0); -92 -93 result = instance.compareTo(that3); -94 assertTrue(result > 0); -95 -96 result = instance.compareTo(that4); -97 assertTrue(result > 0); -98 -99 result = instance.compareTo(that5); -100 assertTrue(result > 0); -101 -102 result = instance.compareTo(that6); -103 assertTrue(result > 0); -104 -105 result = instance.compareTo(that7); -106 assertTrue(result > 0); -107 -108 result = instance.compareTo(that8); -109 assertTrue(result == 0); -110 -111 result = instance.compareTo(that9); -112 assertTrue(result < 0); -113 } -114 } +23 import org.owasp.dependencycheck.BaseTest; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class EvidenceTest extends BaseTest { +30 +31 /** +32 * Test of equals method, of class Evidence. +33 */ +34 @Test +35 public void testEquals() { +36 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); +37 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); +38 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); +39 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); +40 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); +41 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); +42 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); +43 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); +44 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +45 +46 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +47 assertFalse(instance.equals(that0)); +48 assertFalse(instance.equals(that1)); +49 assertFalse(instance.equals(that2)); +50 assertFalse(instance.equals(that3)); +51 assertFalse(instance.equals(that4)); +52 assertFalse(instance.equals(that5)); +53 assertFalse(instance.equals(that6)); +54 assertFalse(instance.equals(that7)); +55 assertTrue(instance.equals(that8)); +56 } +57 +58 @Test +59 public void testHashcodeContract() throws Exception { +60 final Evidence titleCase = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +61 final Evidence lowerCase = new Evidence("manifest", "implementation-title", "spring framework", Confidence.HIGH); +62 assertThat(titleCase, is(equalTo(lowerCase))); +63 assertThat(titleCase.hashCode(), is(equalTo(lowerCase.hashCode()))); +64 } +65 +66 /** +67 * Test of compareTo method, of class Evidence. +68 */ +69 @Test +70 public void testCompareTo() { +71 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); +72 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); +73 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); +74 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); +75 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); +76 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); +77 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); +78 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); +79 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +80 +81 Evidence that9 = new Evidence("manifest", "implementation-title", "zippy", Confidence.HIGH); +82 +83 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); +84 +85 int result = instance.compareTo(that0); +86 assertTrue(result > 0); +87 +88 result = instance.compareTo(that1); +89 assertTrue(result > 0); +90 +91 result = instance.compareTo(that2); +92 assertTrue(result > 0); +93 +94 result = instance.compareTo(that3); +95 assertTrue(result > 0); +96 +97 result = instance.compareTo(that4); +98 assertTrue(result > 0); +99 +100 result = instance.compareTo(that5); +101 assertTrue(result > 0); +102 +103 result = instance.compareTo(that6); +104 assertTrue(result > 0); +105 +106 result = instance.compareTo(that7); +107 assertTrue(result > 0); +108 +109 result = instance.compareTo(that8); +110 assertTrue(result == 0); +111 +112 result = instance.compareTo(that9); +113 assertTrue(result < 0); +114 } +115 }
      diff --git a/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html b/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html new file mode 100644 index 000000000..ceb4706a0 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html @@ -0,0 +1,174 @@ + + + +VulnerabilityTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +3    *
      +4    * Licensed under the Apache License, Version 2.0 (the "License");
      +5    * you may not use this file except in compliance with the License.
      +6    * You may obtain a copy of the License at
      +7    *
      +8    *     http://www.apache.org/licenses/LICENSE-2.0
      +9    *
      +10   * Unless required by applicable law or agreed to in writing, software
      +11   * distributed under the License is distributed on an "AS IS" BASIS,
      +12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      +13   * See the License for the specific language governing permissions and
      +14   * limitations under the License.
      +15   *
      +16   * Copyright (c) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.dependency;
      +19  
      +20  import java.util.Set;
      +21  import org.junit.After;
      +22  import org.junit.AfterClass;
      +23  import static org.junit.Assert.assertEquals;
      +24  import static org.junit.Assert.assertTrue;
      +25  import static org.junit.Assert.assertFalse;
      +26  import org.junit.Before;
      +27  import org.junit.BeforeClass;
      +28  import org.junit.Test;
      +29  import org.owasp.dependencycheck.BaseTest;
      +30  
      +31  /**
      +32   *
      +33   * @author Jens Hausherr
      +34   */
      +35  public class VulnerabilityTest extends BaseTest {
      +36  
      +37      /**
      +38       * Test of equals method, of class VulnerableSoftware.
      +39       */
      +40      @Test
      +41      public void testDuplicateVersions() {
      +42          Vulnerability obj = new Vulnerability();
      +43  
      +44          obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0");
      +45          obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.1");
      +46          obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0");
      +47  
      +48          assertEquals(2, obj.getVulnerableSoftware().size());
      +49      }
      +50  
      +51      @Test
      +52      public void testDpulicateVersionsWithPreviousVersion() {
      +53          Vulnerability obj = new Vulnerability();
      +54          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null);
      +55          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null);
      +56          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null);
      +57          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null);
      +58          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null);
      +59          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null);
      +60          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null);
      +61          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null);
      +62          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null);
      +63          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null);
      +64          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null);
      +65          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null);
      +66          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null);
      +67          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null);
      +68          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null);
      +69          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null);
      +70          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null);
      +71          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null);
      +72          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null);
      +73          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null);
      +74          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null);
      +75          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null);
      +76          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null);
      +77          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null);
      +78          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null);
      +79          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null);
      +80          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null);
      +81          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null);
      +82          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null);
      +83          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null);
      +84          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null);
      +85          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", "1");
      +86          assertEquals(31, obj.getVulnerableSoftware().size());
      +87      }
      +88  
      +89      @Test
      +90      public void testSoftwareSorting() {
      +91          Vulnerability obj = new Vulnerability();
      +92          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null);
      +93          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null);
      +94          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null);
      +95          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null);
      +96          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null);
      +97          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null);
      +98          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null);
      +99          obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null);
      +100         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null);
      +101         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null);
      +102         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null);
      +103         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null);
      +104         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null);
      +105         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null);
      +106         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null);
      +107         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null);
      +108         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null);
      +109         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null);
      +110         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null);
      +111         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null);
      +112         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null);
      +113         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null);
      +114         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null);
      +115         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null);
      +116         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null);
      +117         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null);
      +118         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null);
      +119         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null);
      +120         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null);
      +121         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null);
      +122         obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null);
      +123 
      +124         Set<VulnerableSoftware> software = obj.getVulnerableSoftware();
      +125         VulnerableSoftware vs[] = software.toArray(new VulnerableSoftware[software.size()]);
      +126 
      +127         assertTrue("cpe:/a:hp:system_management_homepage:2.0.0".equals(vs[0].getName()));
      +128         assertTrue("cpe:/a:hp:system_management_homepage:2.0.1".equals(vs[1].getName()));
      +129         assertTrue("cpe:/a:hp:system_management_homepage:2.0.2".equals(vs[2].getName()));
      +130         assertTrue("cpe:/a:hp:system_management_homepage:2.1".equals(vs[3].getName()));
      +131         assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103".equals(vs[4].getName()));
      +132         assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29".equals(vs[5].getName()));
      +133         assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-109".equals(vs[6].getName()));
      +134         assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-118".equals(vs[7].getName()));
      +135         assertTrue("cpe:/a:hp:system_management_homepage:2.1.1".equals(vs[8].getName()));
      +136         assertTrue("cpe:/a:hp:system_management_homepage:2.1.2".equals(vs[9].getName()));
      +137         assertTrue("cpe:/a:hp:system_management_homepage:2.1.2-127".equals(vs[10].getName()));
      +138         assertTrue("cpe:/a:hp:system_management_homepage:2.1.3".equals(vs[11].getName()));
      +139         assertTrue("cpe:/a:hp:system_management_homepage:2.1.3.132".equals(vs[12].getName()));
      +140         assertTrue("cpe:/a:hp:system_management_homepage:2.1.4".equals(vs[13].getName()));
      +141         assertTrue("cpe:/a:hp:system_management_homepage:2.1.4-143".equals(vs[14].getName()));
      +142         assertTrue("cpe:/a:hp:system_management_homepage:2.1.5".equals(vs[15].getName()));
      +143         assertTrue("cpe:/a:hp:system_management_homepage:2.1.5-146".equals(vs[16].getName()));
      +144         assertTrue("cpe:/a:hp:system_management_homepage:2.1.6".equals(vs[17].getName()));
      +145         assertTrue("cpe:/a:hp:system_management_homepage:2.1.6-156".equals(vs[18].getName()));
      +146         assertTrue("cpe:/a:hp:system_management_homepage:2.1.7".equals(vs[19].getName()));
      +147         assertTrue("cpe:/a:hp:system_management_homepage:2.1.7-168".equals(vs[20].getName()));
      +148         assertTrue("cpe:/a:hp:system_management_homepage:2.1.8".equals(vs[21].getName()));
      +149         assertTrue("cpe:/a:hp:system_management_homepage:2.1.8-177".equals(vs[22].getName()));
      +150         assertTrue("cpe:/a:hp:system_management_homepage:2.1.9".equals(vs[23].getName()));
      +151         assertTrue("cpe:/a:hp:system_management_homepage:2.1.9-178".equals(vs[24].getName()));
      +152         assertTrue("cpe:/a:hp:system_management_homepage:2.1.10".equals(vs[25].getName()));
      +153         assertTrue("cpe:/a:hp:system_management_homepage:2.1.10-186".equals(vs[26].getName()));
      +154         assertTrue("cpe:/a:hp:system_management_homepage:2.1.11".equals(vs[27].getName()));
      +155         assertTrue("cpe:/a:hp:system_management_homepage:2.1.11-197".equals(vs[28].getName()));
      +156         assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-118".equals(vs[29].getName()));
      +157         assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-200".equals(vs[30].getName()));
      +158         
      +159     }
      +160 
      +161 }
      +
      +
      + + + diff --git a/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html b/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html index 42b22f787..a7afdef9f 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html +++ b/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html @@ -28,83 +28,138 @@ 20 import org.junit.After; 21 import org.junit.AfterClass; 22 import static org.junit.Assert.assertEquals; -23 import org.junit.Before; -24 import org.junit.BeforeClass; -25 import org.junit.Test; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class VulnerableSoftwareTest { -32 -33 public VulnerableSoftwareTest() { -34 } +23 import static org.junit.Assert.assertTrue; +24 import static org.junit.Assert.assertFalse; +25 import org.junit.Before; +26 import org.junit.BeforeClass; +27 import org.junit.Test; +28 import org.owasp.dependencycheck.BaseTest; +29 +30 /** +31 * +32 * @author Jeremy Long +33 */ +34 public class VulnerableSoftwareTest extends BaseTest { 35 -36 @BeforeClass -37 public static void setUpClass() throws Exception { -38 } -39 -40 @AfterClass -41 public static void tearDownClass() throws Exception { -42 } -43 -44 @Before -45 public void setUp() { +36 /** +37 * Test of equals method, of class VulnerableSoftware. +38 */ +39 @Test +40 public void testEquals() { +41 VulnerableSoftware obj = new VulnerableSoftware(); +42 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +43 VulnerableSoftware instance = new VulnerableSoftware(); +44 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +45 assertFalse(instance.equals(obj)); 46 } 47 -48 @After -49 public void tearDown() { -50 } -51 -52 /** -53 * Test of equals method, of class VulnerableSoftware. -54 */ -55 @Test -56 public void testEquals() { -57 VulnerableSoftware obj = new VulnerableSoftware(); -58 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -59 VulnerableSoftware instance = new VulnerableSoftware(); -60 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -61 boolean expResult = false; -62 boolean result = instance.equals(obj); -63 assertEquals(expResult, result); -64 } -65 -66 /** -67 * Test of hashCode method, of class VulnerableSoftware. -68 */ -69 @Test -70 public void testHashCode() { -71 VulnerableSoftware instance = new VulnerableSoftware(); -72 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -73 int expResult = 1849413912; -74 int result = instance.hashCode(); -75 assertEquals(expResult, result); -76 } -77 -78 /** -79 * Test of compareTo method, of class VulnerableSoftware. -80 */ -81 @Test -82 public void testCompareTo() { -83 VulnerableSoftware vs = new VulnerableSoftware(); -84 vs.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -85 VulnerableSoftware instance = new VulnerableSoftware(); -86 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -87 int expResult = -2; -88 int result = instance.compareTo(vs); -89 assertEquals(expResult, result); -90 -91 vs = new VulnerableSoftware(); -92 vs.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024103"); -93 instance = new VulnerableSoftware(); -94 instance.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024104"); -95 expResult = 1; -96 result = instance.compareTo(vs); -97 assertEquals(expResult, result); -98 } -99 } +48 /** +49 * Test of equals method, of class VulnerableSoftware. +50 */ +51 @Test +52 public void testEquals2() { +53 VulnerableSoftware obj = new VulnerableSoftware(); +54 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +55 VulnerableSoftware instance = new VulnerableSoftware(); +56 instance.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +57 obj.setPreviousVersion("1"); +58 assertTrue(instance.equals(obj)); +59 } +60 +61 /** +62 * Test of hashCode method, of class VulnerableSoftware. +63 */ +64 @Test +65 public void testHashCode() { +66 VulnerableSoftware instance = new VulnerableSoftware(); +67 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +68 int expResult = 1849413912; +69 int result = instance.hashCode(); +70 assertEquals(expResult, result); +71 } +72 +73 /** +74 * Test of compareTo method, of class VulnerableSoftware. +75 */ +76 @Test +77 public void testCompareTo() { +78 VulnerableSoftware vs = new VulnerableSoftware(); +79 vs.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +80 VulnerableSoftware instance = new VulnerableSoftware(); +81 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +82 int expResult = -2; +83 int result = instance.compareTo(vs); +84 assertEquals(expResult, result); +85 +86 vs = new VulnerableSoftware(); +87 vs.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024103"); +88 instance = new VulnerableSoftware(); +89 instance.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024104"); +90 expResult = 1; +91 result = instance.compareTo(vs); +92 assertEquals(expResult, result); +93 } +94 +95 @Test +96 public void testCompareToNonNumerical() { +97 VulnerableSoftware vs = new VulnerableSoftware(); +98 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +99 VulnerableSoftware vs1 = new VulnerableSoftware(); +100 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +101 vs1.setPreviousVersion("1"); +102 assertEquals(0, vs.compareTo(vs1)); +103 assertEquals(0, vs1.compareTo(vs)); +104 } +105 +106 @Test +107 public void testCompareToComplex() { +108 VulnerableSoftware vs = new VulnerableSoftware(); +109 VulnerableSoftware vs1 = new VulnerableSoftware(); +110 +111 vs.setCpe("2.1"); +112 vs1.setCpe("2.1.10"); +113 assertTrue(vs.compareTo(vs1) < 0); +114 +115 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.1"); +116 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); +117 assertTrue(vs.compareTo(vs1) < 0); +118 +119 vs.setCpe("10"); +120 vs1.setCpe("10-186"); +121 assertTrue(vs.compareTo(vs1) < 0); +122 +123 vs.setCpe("2.1.10"); +124 vs1.setCpe("2.1.10-186"); +125 assertTrue(vs.compareTo(vs1) < 0); +126 +127 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); +128 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10-186"); +129 assertTrue(vs.compareTo(vs1) < 0); +130 //assertTrue(vs1.compareTo(vs)>0); +131 } +132 +133 @Test +134 public void testEqualsPreviousVersion() { +135 VulnerableSoftware vs = new VulnerableSoftware(); +136 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +137 VulnerableSoftware vs1 = new VulnerableSoftware(); +138 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +139 vs1.setPreviousVersion("1"); +140 assertEquals(vs, vs1); +141 assertEquals(vs1, vs); +142 +143 } +144 +145 @Test +146 public void testParseCPE() { +147 VulnerableSoftware vs = new VulnerableSoftware(); +148 /* Version for test taken from CVE-2008-2079 */ +149 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +150 assertEquals("mysql", vs.getVendor()); +151 assertEquals("mysql", vs.getProduct()); +152 assertEquals("5.1.23a", vs.getVersion()); +153 } +154 }
      diff --git a/xref-test/org/owasp/dependencycheck/dependency/package-frame.html b/xref-test/org/owasp/dependencycheck/dependency/package-frame.html index 2b4c6937c..2ff5cb746 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/dependency/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.dependency @@ -20,6 +20,9 @@
    237. EvidenceTest +
    238. +
    239. + VulnerabilityTest
    240. VulnerableSoftwareTest diff --git a/xref-test/org/owasp/dependencycheck/dependency/package-summary.html b/xref-test/org/owasp/dependencycheck/dependency/package-summary.html index 637894781..b74bd7184 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/dependency/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.dependency @@ -44,6 +44,11 @@ EvidenceTest + + + + VulnerabilityTest + diff --git a/xref-test/org/owasp/dependencycheck/maven/package-frame.html b/xref-test/org/owasp/dependencycheck/maven/package-frame.html index 5807480d6..895786b22 100644 --- a/xref-test/org/owasp/dependencycheck/maven/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/maven/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.maven + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven diff --git a/xref-test/org/owasp/dependencycheck/maven/package-summary.html b/xref-test/org/owasp/dependencycheck/maven/package-summary.html index 4854f7c59..22f65ff7a 100644 --- a/xref-test/org/owasp/dependencycheck/maven/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/maven/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.maven + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven diff --git a/xref-test/org/owasp/dependencycheck/package-frame.html b/xref-test/org/owasp/dependencycheck/package-frame.html index 0cf80d0e8..11d4c3dc5 100644 --- a/xref-test/org/owasp/dependencycheck/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/xref-test/org/owasp/dependencycheck/package-summary.html b/xref-test/org/owasp/dependencycheck/package-summary.html index 33acb1955..f23ab7a94 100644 --- a/xref-test/org/owasp/dependencycheck/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html b/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html index 12d3e3b01..89534aafb 100644 --- a/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html +++ b/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html @@ -34,136 +34,132 @@ 26 import javax.xml.validation.Validator; 27 import org.junit.Before; 28 import org.junit.Test; -29 import org.owasp.dependencycheck.BaseTest; -30 import org.owasp.dependencycheck.Engine; -31 import org.owasp.dependencycheck.data.nvdcve.CveDB; -32 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -33 import org.owasp.dependencycheck.utils.Settings; -34 -35 /** -36 * -37 * @author Jeremy Long -38 */ -39 public class ReportGeneratorIntegrationTest extends BaseTest { -40 -41 @Before -42 public void setUp() throws Exception { -43 org.owasp.dependencycheck.BaseDBTestCase.ensureDBExists(); -44 } -45 -46 /** -47 * Test of generateReport method, of class ReportGenerator. -48 * -49 * @throws Exception is thrown when an exception occurs. -50 */ -51 @Test -52 public void testGenerateReport() throws Exception { -53 String templateName = "HtmlReport"; -54 // File f = new File("target/test-reports"); -55 // if (!f.exists()) { -56 // f.mkdir(); -57 // } -58 // String writeTo = "target/test-reports/Report.html"; -59 // Map<String, Object> properties = new HashMap<String, Object>(); -60 // Dependency d = new Dependency(); -61 // d.setFileName("FileName.jar"); -62 // d.setActualFilePath("lib/FileName.jar"); -63 // d.addCPEentry("cpe://a:/some:cpe:1.0"); +29 import org.owasp.dependencycheck.BaseDBTestCase; +30 import org.owasp.dependencycheck.BaseTest; +31 import org.owasp.dependencycheck.Engine; +32 import org.owasp.dependencycheck.data.nvdcve.CveDB; +33 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +34 import org.owasp.dependencycheck.utils.Settings; +35 +36 /** +37 * +38 * @author Jeremy Long +39 */ +40 public class ReportGeneratorIntegrationTest extends BaseDBTestCase { +41 +42 /** +43 * Test of generateReport method, of class ReportGenerator. +44 * +45 * @throws Exception is thrown when an exception occurs. +46 */ +47 @Test +48 public void testGenerateReport() throws Exception { +49 String templateName = "HtmlReport"; +50 // File f = new File("target/test-reports"); +51 // if (!f.exists()) { +52 // f.mkdir(); +53 // } +54 // String writeTo = "target/test-reports/Report.html"; +55 // Map<String, Object> properties = new HashMap<String, Object>(); +56 // Dependency d = new Dependency(); +57 // d.setFileName("FileName.jar"); +58 // d.setActualFilePath("lib/FileName.jar"); +59 // d.addCPEentry("cpe://a:/some:cpe:1.0"); +60 // +61 // List<Dependency> dependencies = new ArrayList<Dependency>(); +62 // d.getProductEvidence().addEvidence("jar","filename","<test>test", Confidence.HIGH); +63 // d.getProductEvidence().addEvidence("manifest","vendor","<test>test", Confidence.HIGH); 64 // -65 // List<Dependency> dependencies = new ArrayList<Dependency>(); -66 // d.getProductEvidence().addEvidence("jar","filename","<test>test", Confidence.HIGH); -67 // d.getProductEvidence().addEvidence("manifest","vendor","<test>test", Confidence.HIGH); -68 // -69 // for (Evidence e : d.getProductEvidence().iterator(Confidence.HIGH)) { -70 // String t = e.getValue(); -71 // } -72 // dependencies.add(d); -73 // -74 // Dependency d2 = new Dependency(); -75 // d2.setFileName("Another.jar"); -76 // d2.setActualFilePath("lib/Another.jar"); -77 // d2.addCPEentry("cpe://a:/another:cpe:1.0"); -78 // d2.addCPEentry("cpe://a:/another:cpe:1.1"); -79 // d2.addCPEentry("cpe://a:/another:cpe:1.2"); -80 // d2.getProductEvidence().addEvidence("jar","filename","another.jar", Confidence.HIGH); -81 // d2.getProductEvidence().addEvidence("manifest","vendor","Company A", Confidence.MEDIUM); +65 // for (Evidence e : d.getProductEvidence().iterator(Confidence.HIGH)) { +66 // String t = e.getValue(); +67 // } +68 // dependencies.add(d); +69 // +70 // Dependency d2 = new Dependency(); +71 // d2.setFileName("Another.jar"); +72 // d2.setActualFilePath("lib/Another.jar"); +73 // d2.addCPEentry("cpe://a:/another:cpe:1.0"); +74 // d2.addCPEentry("cpe://a:/another:cpe:1.1"); +75 // d2.addCPEentry("cpe://a:/another:cpe:1.2"); +76 // d2.getProductEvidence().addEvidence("jar","filename","another.jar", Confidence.HIGH); +77 // d2.getProductEvidence().addEvidence("manifest","vendor","Company A", Confidence.MEDIUM); +78 // +79 // for (Evidence e : d2.getProductEvidence().iterator(Confidence.HIGH)) { +80 // String t = e.getValue(); +81 // } 82 // -83 // for (Evidence e : d2.getProductEvidence().iterator(Confidence.HIGH)) { -84 // String t = e.getValue(); -85 // } -86 // -87 // dependencies.add(d2); -88 // -89 // Dependency d3 = new Dependency(); -90 // d3.setFileName("Third.jar"); -91 // d3.setActualFilePath("lib/Third.jar"); -92 // d3.getProductEvidence().addEvidence("jar","filename","third.jar", Confidence.HIGH); +83 // dependencies.add(d2); +84 // +85 // Dependency d3 = new Dependency(); +86 // d3.setFileName("Third.jar"); +87 // d3.setActualFilePath("lib/Third.jar"); +88 // d3.getProductEvidence().addEvidence("jar","filename","third.jar", Confidence.HIGH); +89 // +90 // for (Evidence e : d3.getProductEvidence().iterator(Confidence.HIGH)) { +91 // String t = e.getValue(); +92 // } 93 // -94 // for (Evidence e : d3.getProductEvidence().iterator(Confidence.HIGH)) { -95 // String t = e.getValue(); -96 // } +94 // dependencies.add(d3); +95 // +96 // properties.put("dependencies",dependencies); 97 // -98 // dependencies.add(d3); -99 // -100 // properties.put("dependencies",dependencies); -101 // -102 // ReportGenerator instance = new ReportGenerator(); -103 // instance.generateReport(templateName, writeTo, properties); -104 //assertTrue("need to add a real check here", false); -105 } -106 -107 /** -108 * Generates an XML report containing known vulnerabilities and realistic data and validates the generated XML document -109 * against the XSD. -110 * -111 * @throws Exception -112 */ -113 @Test -114 public void testGenerateXMLReport() throws Exception { -115 String templateName = "XmlReport"; -116 -117 File f = new File("target/test-reports"); -118 if (!f.exists()) { -119 f.mkdir(); -120 } -121 String writeTo = "target/test-reports/Report.xml"; -122 -123 //File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -124 File struts = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -125 //File axis = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath()); -126 File axis = BaseTest.getResourceAsFile(this, "axis2-adb-1.4.1.jar"); -127 //File jetty = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); -128 File jetty = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar"); -129 -130 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -131 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -132 Engine engine = new Engine(); -133 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -134 -135 engine.scan(struts); -136 engine.scan(axis); -137 engine.scan(jetty); -138 engine.analyzeDependencies(); -139 -140 CveDB cveDB = new CveDB(); -141 cveDB.open(); -142 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); -143 cveDB.close(); -144 -145 ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp); -146 generator.generateReport(templateName, writeTo); -147 -148 engine.cleanup(); -149 -150 InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/dependency-check.1.3.xsd"); -151 StreamSource xsdSource = new StreamSource(xsdStream); -152 StreamSource xmlSource = new StreamSource(new File(writeTo)); -153 SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); -154 Schema schema = sf.newSchema(xsdSource); -155 Validator validator = schema.newValidator(); -156 validator.validate(xmlSource); -157 } -158 } +98 // ReportGenerator instance = new ReportGenerator(); +99 // instance.generateReport(templateName, writeTo, properties); +100 //assertTrue("need to add a real check here", false); +101 } +102 +103 /** +104 * Generates an XML report containing known vulnerabilities and realistic data and validates the generated XML document +105 * against the XSD. +106 * +107 * @throws Exception +108 */ +109 @Test +110 public void testGenerateXMLReport() throws Exception { +111 String templateName = "XmlReport"; +112 +113 File f = new File("target/test-reports"); +114 if (!f.exists()) { +115 f.mkdir(); +116 } +117 String writeTo = "target/test-reports/Report.xml"; +118 +119 //File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +120 File struts = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +121 //File axis = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath()); +122 File axis = BaseTest.getResourceAsFile(this, "axis2-adb-1.4.1.jar"); +123 //File jetty = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); +124 File jetty = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar"); +125 +126 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +127 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +128 Engine engine = new Engine(); +129 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +130 +131 engine.scan(struts); +132 engine.scan(axis); +133 engine.scan(jetty); +134 engine.analyzeDependencies(); +135 +136 CveDB cveDB = new CveDB(); +137 cveDB.open(); +138 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); +139 cveDB.close(); +140 +141 ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp); +142 generator.generateReport(templateName, writeTo); +143 +144 engine.cleanup(); +145 +146 InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/dependency-check.1.3.xsd"); +147 StreamSource xsdSource = new StreamSource(xsdStream); +148 StreamSource xmlSource = new StreamSource(new File(writeTo)); +149 SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); +150 Schema schema = sf.newSchema(xsdSource); +151 Validator validator = schema.newValidator(); +152 validator.validate(xmlSource); +153 } +154 }
      diff --git a/xref-test/org/owasp/dependencycheck/reporting/package-frame.html b/xref-test/org/owasp/dependencycheck/reporting/package-frame.html index c39622ba4..bee3f2ae9 100644 --- a/xref-test/org/owasp/dependencycheck/reporting/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/reporting/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.reporting diff --git a/xref-test/org/owasp/dependencycheck/reporting/package-summary.html b/xref-test/org/owasp/dependencycheck/reporting/package-summary.html index 5b64ef356..1685ecffe 100644 --- a/xref-test/org/owasp/dependencycheck/reporting/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/reporting/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.reporting diff --git a/xref-test/org/owasp/dependencycheck/suppression/PropertyTypeTest.html b/xref-test/org/owasp/dependencycheck/suppression/PropertyTypeTest.html index 3338b4907..1c7dceee9 100644 --- a/xref-test/org/owasp/dependencycheck/suppression/PropertyTypeTest.html +++ b/xref-test/org/owasp/dependencycheck/suppression/PropertyTypeTest.html @@ -33,88 +33,70 @@ 25 import org.junit.Before; 26 import org.junit.BeforeClass; 27 import org.junit.Test; -28 -29 /** -30 * -31 * @author Jeremy Long -32 */ -33 public class PropertyTypeTest { -34 -35 public PropertyTypeTest() { -36 } -37 -38 @BeforeClass -39 public static void setUpClass() { -40 } +28 import org.owasp.dependencycheck.BaseTest; +29 +30 /** +31 * +32 * @author Jeremy Long +33 */ +34 public class PropertyTypeTest extends BaseTest { +35 +36 /** +37 * Test of set and getValue method, of class PropertyType. +38 */ +39 @Test +40 public void testSetGetValue() { 41 -42 @AfterClass -43 public static void tearDownClass() { -44 } -45 -46 @Before -47 public void setUp() { -48 } -49 -50 @After -51 public void tearDown() { -52 } -53 -54 /** -55 * Test of set and getValue method, of class PropertyType. -56 */ -57 @Test -58 public void testSetGetValue() { -59 -60 PropertyType instance = new PropertyType(); -61 String expResult = "test"; -62 instance.setValue(expResult); -63 String result = instance.getValue(); -64 assertEquals(expResult, result); -65 } -66 -67 /** -68 * Test of isRegex method, of class PropertyType. -69 */ -70 @Test -71 public void testIsRegex() { -72 PropertyType instance = new PropertyType(); -73 boolean result = instance.isRegex(); -74 assertFalse(instance.isRegex()); -75 instance.setRegex(true); -76 assertTrue(instance.isRegex()); -77 } +42 PropertyType instance = new PropertyType(); +43 String expResult = "test"; +44 instance.setValue(expResult); +45 String result = instance.getValue(); +46 assertEquals(expResult, result); +47 } +48 +49 /** +50 * Test of isRegex method, of class PropertyType. +51 */ +52 @Test +53 public void testIsRegex() { +54 PropertyType instance = new PropertyType(); +55 boolean result = instance.isRegex(); +56 assertFalse(instance.isRegex()); +57 instance.setRegex(true); +58 assertTrue(instance.isRegex()); +59 } +60 +61 /** +62 * Test of isCaseSensitive method, of class PropertyType. +63 */ +64 @Test +65 public void testIsCaseSensitive() { +66 PropertyType instance = new PropertyType(); +67 assertFalse(instance.isCaseSensitive()); +68 instance.setCaseSensitive(true); +69 assertTrue(instance.isCaseSensitive()); +70 } +71 +72 /** +73 * Test of matches method, of class PropertyType. +74 */ +75 @Test +76 public void testMatches() { +77 String text = "Simple"; 78 -79 /** -80 * Test of isCaseSensitive method, of class PropertyType. -81 */ -82 @Test -83 public void testIsCaseSensitive() { -84 PropertyType instance = new PropertyType(); -85 assertFalse(instance.isCaseSensitive()); -86 instance.setCaseSensitive(true); -87 assertTrue(instance.isCaseSensitive()); -88 } -89 -90 /** -91 * Test of matches method, of class PropertyType. -92 */ -93 @Test -94 public void testMatches() { -95 String text = "Simple"; -96 -97 PropertyType instance = new PropertyType(); -98 instance.setValue("simple"); -99 assertTrue(instance.matches(text)); -100 instance.setCaseSensitive(true); -101 assertFalse(instance.matches(text)); -102 -103 instance.setValue("s.*le"); -104 instance.setRegex(true); -105 assertFalse(instance.matches(text)); -106 instance.setCaseSensitive(false); -107 assertTrue(instance.matches(text)); -108 } -109 } +79 PropertyType instance = new PropertyType(); +80 instance.setValue("simple"); +81 assertTrue(instance.matches(text)); +82 instance.setCaseSensitive(true); +83 assertFalse(instance.matches(text)); +84 +85 instance.setValue("s.*le"); +86 instance.setRegex(true); +87 assertFalse(instance.matches(text)); +88 instance.setCaseSensitive(false); +89 assertTrue(instance.matches(text)); +90 } +91 }
      diff --git a/xref-test/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.html b/xref-test/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.html index 2089d8a73..06f60ec56 100644 --- a/xref-test/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.html +++ b/xref-test/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.html @@ -47,70 +47,51 @@ 39 * 40 * @author Jeremy Long 41 */ -42 public class SuppressionHandlerTest { +42 public class SuppressionHandlerTest extends BaseTest { 43 -44 public SuppressionHandlerTest() { -45 } -46 -47 @BeforeClass -48 public static void setUpClass() { -49 } -50 -51 @AfterClass -52 public static void tearDownClass() { -53 } -54 -55 @Before -56 public void setUp() { -57 } -58 -59 @After -60 public void tearDown() { -61 } -62 -63 /** -64 * Test of getSuppressionRules method, of class SuppressionHandler. -65 * -66 * @throws Exception thrown if there is an exception.... -67 */ -68 @Test -69 public void testHandler() throws Exception { -70 //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); -71 File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); +44 /** +45 * Test of getSuppressionRules method, of class SuppressionHandler. +46 * +47 * @throws Exception thrown if there is an exception.... +48 */ +49 @Test +50 public void testHandler() throws Exception { +51 //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); +52 File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); +53 +54 //File schema = new File(this.getClass().getClassLoader().getResource("schema/suppression.xsd").getPath()); +55 File schema = BaseTest.getResourceAsFile(this, "schema/suppression.xsd"); +56 SuppressionHandler handler = new SuppressionHandler(); +57 +58 SAXParserFactory factory = SAXParserFactory.newInstance(); +59 factory.setNamespaceAware(true); +60 factory.setValidating(true); +61 SAXParser saxParser = factory.newSAXParser(); +62 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); +63 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, schema); +64 XMLReader xmlReader = saxParser.getXMLReader(); +65 xmlReader.setErrorHandler(new SuppressionErrorHandler()); +66 xmlReader.setContentHandler(handler); +67 +68 InputStream inputStream = new FileInputStream(file); +69 Reader reader = new InputStreamReader(inputStream, "UTF-8"); +70 InputSource in = new InputSource(reader); +71 //in.setEncoding("UTF-8"); 72 -73 //File schema = new File(this.getClass().getClassLoader().getResource("schema/suppression.xsd").getPath()); -74 File schema = BaseTest.getResourceAsFile(this, "schema/suppression.xsd"); -75 SuppressionHandler handler = new SuppressionHandler(); -76 -77 SAXParserFactory factory = SAXParserFactory.newInstance(); -78 factory.setNamespaceAware(true); -79 factory.setValidating(true); -80 SAXParser saxParser = factory.newSAXParser(); -81 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); -82 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, schema); -83 XMLReader xmlReader = saxParser.getXMLReader(); -84 xmlReader.setErrorHandler(new SuppressionErrorHandler()); -85 xmlReader.setContentHandler(handler); -86 -87 InputStream inputStream = new FileInputStream(file); -88 Reader reader = new InputStreamReader(inputStream, "UTF-8"); -89 InputSource in = new InputSource(reader); -90 //in.setEncoding("UTF-8"); -91 -92 xmlReader.parse(in); -93 -94 List<SuppressionRule> result = handler.getSuppressionRules(); -95 assertTrue(result.size() > 3); -96 int baseCount = 0; -97 for (SuppressionRule r : result) { -98 if (r.isBase()) { -99 baseCount++; -100 } -101 } -102 assertTrue(baseCount > 0); -103 -104 } -105 } +73 xmlReader.parse(in); +74 +75 List<SuppressionRule> result = handler.getSuppressionRules(); +76 assertTrue(result.size() > 3); +77 int baseCount = 0; +78 for (SuppressionRule r : result) { +79 if (r.isBase()) { +80 baseCount++; +81 } +82 } +83 assertTrue(baseCount > 0); +84 +85 } +86 }
      diff --git a/xref-test/org/owasp/dependencycheck/suppression/SuppressionParserTest.html b/xref-test/org/owasp/dependencycheck/suppression/SuppressionParserTest.html index 6e9743f85..c4baf4178 100644 --- a/xref-test/org/owasp/dependencycheck/suppression/SuppressionParserTest.html +++ b/xref-test/org/owasp/dependencycheck/suppression/SuppressionParserTest.html @@ -40,39 +40,20 @@ 32 * 33 * @author Jeremy Long 34 */ -35 public class SuppressionParserTest { +35 public class SuppressionParserTest extends BaseTest { 36 -37 public SuppressionParserTest() { -38 } -39 -40 @BeforeClass -41 public static void setUpClass() { -42 } -43 -44 @AfterClass -45 public static void tearDownClass() { -46 } -47 -48 @Before -49 public void setUp() { -50 } -51 -52 @After -53 public void tearDown() { -54 } -55 -56 /** -57 * Test of parseSuppressionRules method, of class SuppressionParser. -58 */ -59 @Test -60 public void testParseSuppressionRules() throws Exception { -61 //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); -62 File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); -63 SuppressionParser instance = new SuppressionParser(); -64 List<SuppressionRule> result = instance.parseSuppressionRules(file); -65 assertTrue(result.size() > 3); -66 } -67 } +37 /** +38 * Test of parseSuppressionRules method, of class SuppressionParser. +39 */ +40 @Test +41 public void testParseSuppressionRules() throws Exception { +42 //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); +43 File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); +44 SuppressionParser instance = new SuppressionParser(); +45 List<SuppressionRule> result = instance.parseSuppressionRules(file); +46 assertTrue(result.size() > 3); +47 } +48 }
      diff --git a/xref-test/org/owasp/dependencycheck/suppression/SuppressionRuleTest.html b/xref-test/org/owasp/dependencycheck/suppression/SuppressionRuleTest.html index 55e7d1959..c7d9dc4b7 100644 --- a/xref-test/org/owasp/dependencycheck/suppression/SuppressionRuleTest.html +++ b/xref-test/org/owasp/dependencycheck/suppression/SuppressionRuleTest.html @@ -42,7 +42,7 @@ 34 * 35 * @author Jeremy Long 36 */ -37 public class SuppressionRuleTest { +37 public class SuppressionRuleTest extends BaseTest { 38 39 //<editor-fold defaultstate="collapsed" desc="Stupid tests of properties"> 40 /** diff --git a/xref-test/org/owasp/dependencycheck/suppression/package-frame.html b/xref-test/org/owasp/dependencycheck/suppression/package-frame.html index 7e74098fd..aa9730cfc 100644 --- a/xref-test/org/owasp/dependencycheck/suppression/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/suppression/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.suppression diff --git a/xref-test/org/owasp/dependencycheck/suppression/package-summary.html b/xref-test/org/owasp/dependencycheck/suppression/package-summary.html index 17ae0c4da..73bd46da6 100644 --- a/xref-test/org/owasp/dependencycheck/suppression/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/suppression/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.suppression diff --git a/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html b/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html index 75ec6af15..c42369b36 100644 --- a/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html b/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html index b6d2fdd67..efab4a3d3 100644 --- a/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html b/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html index b8f4b8aff..998326f28 100644 --- a/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html +++ b/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html @@ -30,53 +30,35 @@ 22 import org.junit.Before; 23 import org.junit.BeforeClass; 24 import org.junit.Test; -25 -26 /** -27 * -28 * @author Jeremy Long -29 */ -30 public class DateUtilTest { -31 -32 public DateUtilTest() { -33 } -34 -35 @BeforeClass -36 public static void setUpClass() { -37 } -38 -39 @AfterClass -40 public static void tearDownClass() { -41 } -42 -43 @Before -44 public void setUp() { -45 } +25 import org.owasp.dependencycheck.BaseTest; +26 +27 /** +28 * +29 * @author Jeremy Long +30 */ +31 public class DateUtilTest extends BaseTest { +32 +33 /** +34 * Test of withinDateRange method, of class DateUtil. +35 */ +36 @Test +37 public void testWithinDateRange() { +38 Calendar c = Calendar.getInstance(); +39 +40 long current = c.getTimeInMillis(); +41 long lastRun = c.getTimeInMillis() - (3 * (1000 * 60 * 60 * 24)); +42 int range = 7; // 7 days +43 boolean expResult = true; +44 boolean result = DateUtil.withinDateRange(lastRun, current, range); +45 assertEquals(expResult, result); 46 -47 @After -48 public void tearDown() { -49 } -50 -51 /** -52 * Test of withinDateRange method, of class DateUtil. -53 */ -54 @Test -55 public void testWithinDateRange() { -56 Calendar c = Calendar.getInstance(); -57 -58 long current = c.getTimeInMillis(); -59 long lastRun = c.getTimeInMillis() - (3 * (1000 * 60 * 60 * 24)); -60 int range = 7; // 7 days -61 boolean expResult = true; -62 boolean result = DateUtil.withinDateRange(lastRun, current, range); -63 assertEquals(expResult, result); -64 -65 lastRun = c.getTimeInMillis() - (8 * (1000 * 60 * 60 * 24)); -66 expResult = false; -67 result = DateUtil.withinDateRange(lastRun, current, range); -68 assertEquals(expResult, result); -69 } -70 -71 } +47 lastRun = c.getTimeInMillis() - (8 * (1000 * 60 * 60 * 24)); +48 expResult = false; +49 result = DateUtil.withinDateRange(lastRun, current, range); +50 assertEquals(expResult, result); +51 } +52 +53 }
      diff --git a/xref-test/org/owasp/dependencycheck/utils/DependencyVersionTest.html b/xref-test/org/owasp/dependencycheck/utils/DependencyVersionTest.html index 8edf796ee..931321b6a 100644 --- a/xref-test/org/owasp/dependencycheck/utils/DependencyVersionTest.html +++ b/xref-test/org/owasp/dependencycheck/utils/DependencyVersionTest.html @@ -32,179 +32,180 @@ 24 import static org.junit.Assert.assertEquals; 25 import static org.junit.Assert.assertTrue; 26 import org.junit.Test; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class DependencyVersionTest { -33 -34 /** -35 * Test of parseVersion method, of class DependencyVersion. -36 */ -37 @Test -38 public void testParseVersion() { -39 String version = "1.2r1"; -40 DependencyVersion instance = new DependencyVersion(); -41 instance.parseVersion(version); -42 List<String> parts = instance.getVersionParts(); -43 assertEquals(3, parts.size()); -44 assertEquals("1", parts.get(0)); -45 assertEquals("2", parts.get(1)); -46 assertEquals("r1", parts.get(2)); -47 -48 instance.parseVersion("x6.0"); -49 parts = instance.getVersionParts(); -50 assertEquals(2, parts.size()); -51 assertEquals("x6", parts.get(0)); -52 assertEquals("0", parts.get(1)); -53 // TODO(code review): should this be here/do something? -54 //assertEquals("0", parts.get(2)); -55 -56 } -57 -58 /** -59 * Test of iterator method, of class DependencyVersion. -60 */ -61 @Test -62 public void testIterator() { -63 DependencyVersion instance = new DependencyVersion("1.2.3"); -64 Iterator<String> result = instance.iterator(); -65 assertTrue(result.hasNext()); -66 int count = 1; -67 while (result.hasNext()) { -68 String v = result.next(); -69 assertTrue(String.valueOf(count++).equals(v)); -70 } -71 } -72 -73 /** -74 * Test of toString method, of class DependencyVersion. -75 */ -76 @Test -77 public void testToString() { -78 DependencyVersion instance = new DependencyVersion("1.2.3r1"); -79 String expResult = "1.2.3.r1"; -80 String result = instance.toString(); -81 assertEquals(expResult, result); -82 } -83 -84 /** -85 * Test of equals method, of class DependencyVersion. -86 */ -87 @Test -88 public void testEquals() { -89 DependencyVersion obj = new DependencyVersion("1.2.3.r1"); -90 DependencyVersion instance = new DependencyVersion("1.2.3"); -91 boolean expResult = false; -92 boolean result = instance.equals(obj); -93 assertEquals(expResult, result); -94 obj = new DependencyVersion("1.2.3"); -95 expResult = true; -96 result = instance.equals(obj); -97 assertEquals(expResult, result); -98 } -99 -100 /** -101 * Test of hashCode method, of class DependencyVersion. -102 */ -103 @Test -104 public void testHashCode() { -105 DependencyVersion instance = new DependencyVersion("3.2.1"); -106 int expResult = 80756; -107 int result = instance.hashCode(); -108 assertEquals(expResult, result); -109 } -110 -111 /** -112 * Test of matchesAtLeastThreeLevels method, of class DependencyVersion. -113 */ -114 @Test -115 public void testMatchesAtLeastThreeLevels() { -116 -117 DependencyVersion instance = new DependencyVersion("2.3.16.3"); -118 DependencyVersion version = new DependencyVersion("2.3.16.4"); -119 //true tests -120 assertEquals(true, instance.matchesAtLeastThreeLevels(version)); -121 version = new DependencyVersion("2.3"); -122 assertEquals(true, instance.matchesAtLeastThreeLevels(version)); -123 //false tests -124 version = new DependencyVersion("2.3.16.1"); -125 assertEquals(false, instance.matchesAtLeastThreeLevels(version)); -126 version = new DependencyVersion("2"); -127 assertEquals(false, instance.matchesAtLeastThreeLevels(version)); -128 } -129 -130 /** -131 * Test of compareTo method, of class DependencyVersion. -132 */ -133 @Test -134 public void testCompareTo() { -135 DependencyVersion instance = new DependencyVersion("1.2.3"); -136 DependencyVersion version = new DependencyVersion("1.2.3"); -137 assertEquals(0, instance.compareTo(version)); -138 version = new DependencyVersion("1.1"); -139 assertEquals(1, instance.compareTo(version)); -140 version = new DependencyVersion("1.2"); -141 assertEquals(1, instance.compareTo(version)); -142 version = new DependencyVersion("1.3"); -143 assertEquals(-1, instance.compareTo(version)); -144 version = new DependencyVersion("1.2.3.1"); -145 assertEquals(-1, instance.compareTo(version)); -146 -147 instance = new DependencyVersion("1.0.1n"); -148 version = new DependencyVersion("1.0.1m"); -149 assertEquals(1, instance.compareTo(version)); -150 version = new DependencyVersion("1.0.1n"); -151 assertEquals(0, instance.compareTo(version)); -152 version = new DependencyVersion("1.0.1o"); -153 assertEquals(-1, instance.compareTo(version)); -154 -155 DependencyVersion[] dv = new DependencyVersion[7]; -156 dv[0] = new DependencyVersion("2.1.3"); -157 dv[1] = new DependencyVersion("2.1.3.r2"); -158 dv[2] = new DependencyVersion("2.1.3.r1"); -159 dv[3] = new DependencyVersion("1.2.3.1"); -160 dv[4] = new DependencyVersion("1.2.3"); -161 dv[5] = new DependencyVersion("2"); -162 dv[6] = new DependencyVersion("-"); -163 -164 DependencyVersion[] expected = new DependencyVersion[7]; -165 expected[0] = new DependencyVersion("-"); -166 expected[1] = new DependencyVersion("1.2.3"); -167 expected[2] = new DependencyVersion("1.2.3.1"); -168 expected[3] = new DependencyVersion("2"); -169 expected[4] = new DependencyVersion("2.1.3"); -170 expected[5] = new DependencyVersion("2.1.3.r1"); -171 expected[6] = new DependencyVersion("2.1.3.r2"); -172 java.util.Arrays.sort(dv); -173 -174 assertArrayEquals(expected, dv); -175 } -176 -177 /** -178 * Test of getVersionParts method, of class DependencyVersion. -179 */ -180 @Test -181 public void testGetVersionParts() { -182 DependencyVersion instance = new DependencyVersion(); -183 List<String> versionParts = Arrays.asList("1", "1", "1"); -184 instance.setVersionParts(versionParts); -185 List<String> expResult = Arrays.asList("1", "1", "1"); -186 List<String> result = instance.getVersionParts(); -187 assertEquals(expResult, result); -188 } -189 -190 /** -191 * Test of setVersionParts method, of class DependencyVersion. -192 */ -193 @Test -194 public void testSetVersionParts() { -195 List<String> versionParts = Arrays.asList("1", "1", "1"); -196 DependencyVersion instance = new DependencyVersion(); -197 instance.setVersionParts(versionParts); -198 } -199 } +27 import org.owasp.dependencycheck.BaseTest; +28 +29 /** +30 * +31 * @author Jeremy Long +32 */ +33 public class DependencyVersionTest extends BaseTest { +34 +35 /** +36 * Test of parseVersion method, of class DependencyVersion. +37 */ +38 @Test +39 public void testParseVersion() { +40 String version = "1.2r1"; +41 DependencyVersion instance = new DependencyVersion(); +42 instance.parseVersion(version); +43 List<String> parts = instance.getVersionParts(); +44 assertEquals(3, parts.size()); +45 assertEquals("1", parts.get(0)); +46 assertEquals("2", parts.get(1)); +47 assertEquals("r1", parts.get(2)); +48 +49 instance.parseVersion("x6.0"); +50 parts = instance.getVersionParts(); +51 assertEquals(2, parts.size()); +52 assertEquals("x6", parts.get(0)); +53 assertEquals("0", parts.get(1)); +54 // TODO(code review): should this be here/do something? +55 //assertEquals("0", parts.get(2)); +56 +57 } +58 +59 /** +60 * Test of iterator method, of class DependencyVersion. +61 */ +62 @Test +63 public void testIterator() { +64 DependencyVersion instance = new DependencyVersion("1.2.3"); +65 Iterator<String> result = instance.iterator(); +66 assertTrue(result.hasNext()); +67 int count = 1; +68 while (result.hasNext()) { +69 String v = result.next(); +70 assertTrue(String.valueOf(count++).equals(v)); +71 } +72 } +73 +74 /** +75 * Test of toString method, of class DependencyVersion. +76 */ +77 @Test +78 public void testToString() { +79 DependencyVersion instance = new DependencyVersion("1.2.3r1"); +80 String expResult = "1.2.3.r1"; +81 String result = instance.toString(); +82 assertEquals(expResult, result); +83 } +84 +85 /** +86 * Test of equals method, of class DependencyVersion. +87 */ +88 @Test +89 public void testEquals() { +90 DependencyVersion obj = new DependencyVersion("1.2.3.r1"); +91 DependencyVersion instance = new DependencyVersion("1.2.3"); +92 boolean expResult = false; +93 boolean result = instance.equals(obj); +94 assertEquals(expResult, result); +95 obj = new DependencyVersion("1.2.3"); +96 expResult = true; +97 result = instance.equals(obj); +98 assertEquals(expResult, result); +99 } +100 +101 /** +102 * Test of hashCode method, of class DependencyVersion. +103 */ +104 @Test +105 public void testHashCode() { +106 DependencyVersion instance = new DependencyVersion("3.2.1"); +107 int expResult = 80756; +108 int result = instance.hashCode(); +109 assertEquals(expResult, result); +110 } +111 +112 /** +113 * Test of matchesAtLeastThreeLevels method, of class DependencyVersion. +114 */ +115 @Test +116 public void testMatchesAtLeastThreeLevels() { +117 +118 DependencyVersion instance = new DependencyVersion("2.3.16.3"); +119 DependencyVersion version = new DependencyVersion("2.3.16.4"); +120 //true tests +121 assertEquals(true, instance.matchesAtLeastThreeLevels(version)); +122 version = new DependencyVersion("2.3"); +123 assertEquals(true, instance.matchesAtLeastThreeLevels(version)); +124 //false tests +125 version = new DependencyVersion("2.3.16.1"); +126 assertEquals(false, instance.matchesAtLeastThreeLevels(version)); +127 version = new DependencyVersion("2"); +128 assertEquals(false, instance.matchesAtLeastThreeLevels(version)); +129 } +130 +131 /** +132 * Test of compareTo method, of class DependencyVersion. +133 */ +134 @Test +135 public void testCompareTo() { +136 DependencyVersion instance = new DependencyVersion("1.2.3"); +137 DependencyVersion version = new DependencyVersion("1.2.3"); +138 assertEquals(0, instance.compareTo(version)); +139 version = new DependencyVersion("1.1"); +140 assertEquals(1, instance.compareTo(version)); +141 version = new DependencyVersion("1.2"); +142 assertEquals(1, instance.compareTo(version)); +143 version = new DependencyVersion("1.3"); +144 assertEquals(-1, instance.compareTo(version)); +145 version = new DependencyVersion("1.2.3.1"); +146 assertEquals(-1, instance.compareTo(version)); +147 +148 instance = new DependencyVersion("1.0.1n"); +149 version = new DependencyVersion("1.0.1m"); +150 assertEquals(1, instance.compareTo(version)); +151 version = new DependencyVersion("1.0.1n"); +152 assertEquals(0, instance.compareTo(version)); +153 version = new DependencyVersion("1.0.1o"); +154 assertEquals(-1, instance.compareTo(version)); +155 +156 DependencyVersion[] dv = new DependencyVersion[7]; +157 dv[0] = new DependencyVersion("2.1.3"); +158 dv[1] = new DependencyVersion("2.1.3.r2"); +159 dv[2] = new DependencyVersion("2.1.3.r1"); +160 dv[3] = new DependencyVersion("1.2.3.1"); +161 dv[4] = new DependencyVersion("1.2.3"); +162 dv[5] = new DependencyVersion("2"); +163 dv[6] = new DependencyVersion("-"); +164 +165 DependencyVersion[] expected = new DependencyVersion[7]; +166 expected[0] = new DependencyVersion("-"); +167 expected[1] = new DependencyVersion("1.2.3"); +168 expected[2] = new DependencyVersion("1.2.3.1"); +169 expected[3] = new DependencyVersion("2"); +170 expected[4] = new DependencyVersion("2.1.3"); +171 expected[5] = new DependencyVersion("2.1.3.r1"); +172 expected[6] = new DependencyVersion("2.1.3.r2"); +173 java.util.Arrays.sort(dv); +174 +175 assertArrayEquals(expected, dv); +176 } +177 +178 /** +179 * Test of getVersionParts method, of class DependencyVersion. +180 */ +181 @Test +182 public void testGetVersionParts() { +183 DependencyVersion instance = new DependencyVersion(); +184 List<String> versionParts = Arrays.asList("1", "1", "1"); +185 instance.setVersionParts(versionParts); +186 List<String> expResult = Arrays.asList("1", "1", "1"); +187 List<String> result = instance.getVersionParts(); +188 assertEquals(expResult, result); +189 } +190 +191 /** +192 * Test of setVersionParts method, of class DependencyVersion. +193 */ +194 @Test +195 public void testSetVersionParts() { +196 List<String> versionParts = Arrays.asList("1", "1", "1"); +197 DependencyVersion instance = new DependencyVersion(); +198 instance.setVersionParts(versionParts); +199 } +200 }
      diff --git a/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html b/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html index 085e4e6a1..9bcab3e6d 100644 --- a/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html +++ b/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html @@ -32,63 +32,45 @@ 24 import org.junit.Before; 25 import org.junit.BeforeClass; 26 import org.junit.Test; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class DependencyVersionUtilTest { -33 -34 public DependencyVersionUtilTest() { -35 } -36 -37 @BeforeClass -38 public static void setUpClass() throws Exception { -39 } -40 -41 @AfterClass -42 public static void tearDownClass() throws Exception { -43 } -44 -45 @Before -46 public void setUp() { -47 } +27 import org.owasp.dependencycheck.BaseTest; +28 +29 /** +30 * +31 * @author Jeremy Long +32 */ +33 public class DependencyVersionUtilTest extends BaseTest { +34 +35 /** +36 * Test of parseVersion method, of class DependencyVersionUtil. +37 */ +38 @Test +39 public void testParseVersion() { +40 final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar", +41 "lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar", +42 "lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar", +43 "-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar", +44 "plone.rfc822-1.1.1-py2-none-any.whl"}; +45 final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1", +46 "2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", +47 "2.2.8.02", "1.1.1"}; 48 -49 @After -50 public void tearDown() { -51 } -52 -53 /** -54 * Test of parseVersion method, of class DependencyVersionUtil. -55 */ -56 @Test -57 public void testParseVersion() { -58 final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar", -59 "lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar", -60 "lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar", -61 "-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar", -62 "plone.rfc822-1.1.1-py2-none-any.whl"}; -63 final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1", -64 "2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", -65 "2.2.8.02", "1.1.1"}; -66 -67 for (int i = 0; i < fileName.length; i++) { -68 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]); -69 String result = null; -70 if (version != null) { -71 result = version.toString(); -72 } -73 assertEquals("Failed extraction on \"" + fileName[i] + "\".", expResult[i], result); -74 } -75 -76 String[] failingNames = {"no-version-identified.jar", "somelib-04aug2000r7-dev.jar", /*"no.version15.jar",*/ -77 "lib_1.0_spec-1.1.jar", "lib-api_1.0_spec-1.0.1.jar"}; -78 for (String failingName : failingNames) { -79 final DependencyVersion version = DependencyVersionUtil.parseVersion(failingName); -80 assertNull("Found version in name that should have failed \"" + failingName + "\".", version); -81 } -82 } -83 } +49 for (int i = 0; i < fileName.length; i++) { +50 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]); +51 String result = null; +52 if (version != null) { +53 result = version.toString(); +54 } +55 assertEquals("Failed extraction on \"" + fileName[i] + "\".", expResult[i], result); +56 } +57 +58 String[] failingNames = {"no-version-identified.jar", "somelib-04aug2000r7-dev.jar", /*"no.version15.jar",*/ +59 "lib_1.0_spec-1.1.jar", "lib-api_1.0_spec-1.0.1.jar"}; +60 for (String failingName : failingNames) { +61 final DependencyVersion version = DependencyVersionUtil.parseVersion(failingName); +62 assertNull("Found version in name that should have failed \"" + failingName + "\".", version); +63 } +64 } +65 }
      diff --git a/xref-test/org/owasp/dependencycheck/utils/FilterTest.html b/xref-test/org/owasp/dependencycheck/utils/FilterTest.html index be16a51a8..64052cd26 100644 --- a/xref-test/org/owasp/dependencycheck/utils/FilterTest.html +++ b/xref-test/org/owasp/dependencycheck/utils/FilterTest.html @@ -31,53 +31,54 @@ 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertTrue; 25 import org.junit.Test; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class FilterTest { -32 -33 /** -34 * Test of passes method, of class Filter. -35 */ -36 @Test -37 public void testPasses() { -38 String keep = "keep"; -39 String fail = "fail"; -40 -41 assertTrue("String contained keep - but passes returned false.", TEST_FILTER.passes(keep)); -42 assertFalse("String contained fail - but passes returned true.", TEST_FILTER.passes(fail)); -43 } -44 -45 /** -46 * Test of filter method, of class Filter. -47 */ -48 @Test -49 public void testFilter_Iterable() { -50 List<String> testData = new ArrayList<String>(); -51 testData.add("keep"); -52 testData.add("remove"); -53 testData.add("keep"); -54 -55 List<String> expResults = new ArrayList<String>(); -56 expResults.add("keep"); +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public class FilterTest extends BaseTest { +33 +34 /** +35 * Test of passes method, of class Filter. +36 */ +37 @Test +38 public void testPasses() { +39 String keep = "keep"; +40 String fail = "fail"; +41 +42 assertTrue("String contained keep - but passes returned false.", TEST_FILTER.passes(keep)); +43 assertFalse("String contained fail - but passes returned true.", TEST_FILTER.passes(fail)); +44 } +45 +46 /** +47 * Test of filter method, of class Filter. +48 */ +49 @Test +50 public void testFilter_Iterable() { +51 List<String> testData = new ArrayList<String>(); +52 testData.add("keep"); +53 testData.add("remove"); +54 testData.add("keep"); +55 +56 List<String> expResults = new ArrayList<String>(); 57 expResults.add("keep"); -58 -59 List<String> actResults = new ArrayList<String>(); -60 for (String s : TEST_FILTER.filter(testData)) { -61 actResults.add(s); -62 } -63 assertArrayEquals(expResults.toArray(), actResults.toArray()); -64 } -65 private static final Filter<String> TEST_FILTER -66 = new Filter<String>() { -67 @Override -68 public boolean passes(String str) { -69 return str.contains("keep"); -70 } -71 }; -72 } +58 expResults.add("keep"); +59 +60 List<String> actResults = new ArrayList<String>(); +61 for (String s : TEST_FILTER.filter(testData)) { +62 actResults.add(s); +63 } +64 assertArrayEquals(expResults.toArray(), actResults.toArray()); +65 } +66 private static final Filter<String> TEST_FILTER +67 = new Filter<String>() { +68 @Override +69 public boolean passes(String str) { +70 return str.contains("keep"); +71 } +72 }; +73 }
      diff --git a/xref-test/org/owasp/dependencycheck/utils/package-frame.html b/xref-test/org/owasp/dependencycheck/utils/package-frame.html index d58b96d02..5a93cdd95 100644 --- a/xref-test/org/owasp/dependencycheck/utils/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/xref-test/org/owasp/dependencycheck/utils/package-summary.html b/xref-test/org/owasp/dependencycheck/utils/package-summary.html index 0b0f97667..1a51ba9bf 100644 --- a/xref-test/org/owasp/dependencycheck/utils/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/xref-test/org/owasp/dependencycheck/xml/pom/ModelTest.html b/xref-test/org/owasp/dependencycheck/xml/pom/ModelTest.html index f623c2f59..a53f4d292 100644 --- a/xref-test/org/owasp/dependencycheck/xml/pom/ModelTest.html +++ b/xref-test/org/owasp/dependencycheck/xml/pom/ModelTest.html @@ -31,266 +31,267 @@ 23 24 import org.junit.Test; 25 import static org.junit.Assert.*; -26 -27 /** -28 * -29 * @author jeremy -30 */ -31 public class ModelTest { -32 -33 /** -34 * Test of getName method, of class Model. -35 */ -36 @Test -37 public void testGetName() { -38 Model instance = new Model(); -39 instance.setName(""); -40 String expResult = ""; -41 String result = instance.getName(); -42 assertEquals(expResult, result); -43 } -44 -45 /** -46 * Test of setName method, of class Model. -47 */ -48 @Test -49 public void testSetName() { -50 String name = ""; -51 Model instance = new Model(); -52 instance.setName(name); -53 } -54 -55 /** -56 * Test of getOrganization method, of class Model. -57 */ -58 @Test -59 public void testGetOrganization() { -60 Model instance = new Model(); -61 instance.setOrganization(""); -62 String expResult = ""; -63 String result = instance.getOrganization(); -64 assertEquals(expResult, result); -65 } -66 -67 /** -68 * Test of setOrganization method, of class Model. -69 */ -70 @Test -71 public void testSetOrganization() { -72 String organization = ""; -73 Model instance = new Model(); -74 instance.setOrganization(organization); -75 } -76 -77 /** -78 * Test of getDescription method, of class Model. -79 */ -80 @Test -81 public void testGetDescription() { -82 Model instance = new Model(); -83 instance.setDescription(""); -84 String expResult = ""; -85 String result = instance.getDescription(); -86 assertEquals(expResult, result); -87 } -88 -89 /** -90 * Test of setDescription method, of class Model. -91 */ -92 @Test -93 public void testSetDescription() { -94 String description = ""; -95 Model instance = new Model(); -96 instance.setDescription(description); -97 } -98 -99 /** -100 * Test of getGroupId method, of class Model. -101 */ -102 @Test -103 public void testGetGroupId() { -104 Model instance = new Model(); -105 instance.setGroupId(""); -106 String expResult = ""; -107 String result = instance.getGroupId(); -108 assertEquals(expResult, result); -109 } -110 -111 /** -112 * Test of setGroupId method, of class Model. -113 */ -114 @Test -115 public void testSetGroupId() { -116 String groupId = ""; -117 Model instance = new Model(); -118 instance.setGroupId(groupId); -119 } -120 -121 /** -122 * Test of getArtifactId method, of class Model. -123 */ -124 @Test -125 public void testGetArtifactId() { -126 Model instance = new Model(); -127 instance.setArtifactId(""); -128 String expResult = ""; -129 String result = instance.getArtifactId(); -130 assertEquals(expResult, result); -131 } -132 -133 /** -134 * Test of setArtifactId method, of class Model. -135 */ -136 @Test -137 public void testSetArtifactId() { -138 String artifactId = ""; -139 Model instance = new Model(); -140 instance.setArtifactId(artifactId); -141 } -142 -143 /** -144 * Test of getVersion method, of class Model. -145 */ -146 @Test -147 public void testGetVersion() { -148 Model instance = new Model(); -149 instance.setVersion(""); -150 String expResult = ""; -151 String result = instance.getVersion(); -152 assertEquals(expResult, result); -153 } -154 -155 /** -156 * Test of setVersion method, of class Model. -157 */ -158 @Test -159 public void testSetVersion() { -160 String version = ""; -161 Model instance = new Model(); -162 instance.setVersion(version); -163 } -164 -165 /** -166 * Test of getParentGroupId method, of class Model. -167 */ -168 @Test -169 public void testGetParentGroupId() { -170 Model instance = new Model(); -171 instance.setParentGroupId(""); -172 String expResult = ""; -173 String result = instance.getParentGroupId(); -174 assertEquals(expResult, result); -175 } -176 -177 /** -178 * Test of setParentGroupId method, of class Model. -179 */ -180 @Test -181 public void testSetParentGroupId() { -182 String parentGroupId = ""; -183 Model instance = new Model(); -184 instance.setParentGroupId(parentGroupId); -185 } -186 -187 /** -188 * Test of getParentArtifactId method, of class Model. -189 */ -190 @Test -191 public void testGetParentArtifactId() { -192 Model instance = new Model(); -193 instance.setParentArtifactId(""); -194 String expResult = ""; -195 String result = instance.getParentArtifactId(); -196 assertEquals(expResult, result); -197 } -198 -199 /** -200 * Test of setParentArtifactId method, of class Model. -201 */ -202 @Test -203 public void testSetParentArtifactId() { -204 String parentArtifactId = ""; -205 Model instance = new Model(); -206 instance.setParentArtifactId(parentArtifactId); -207 } -208 -209 /** -210 * Test of getParentVersion method, of class Model. -211 */ -212 @Test -213 public void testGetParentVersion() { -214 Model instance = new Model(); -215 instance.setParentVersion(""); -216 String expResult = ""; -217 String result = instance.getParentVersion(); -218 assertEquals(expResult, result); -219 } -220 -221 /** -222 * Test of setParentVersion method, of class Model. -223 */ -224 @Test -225 public void testSetParentVersion() { -226 String parentVersion = ""; -227 Model instance = new Model(); -228 instance.setParentVersion(parentVersion); -229 } -230 -231 /** -232 * Test of getLicenses method, of class Model. -233 */ -234 @Test -235 public void testGetLicenses() { -236 Model instance = new Model(); -237 instance.addLicense(new License("name", "url")); -238 List<License> expResult = new ArrayList<License>(); -239 expResult.add(new License("name", "url")); -240 List<License> result = instance.getLicenses(); -241 assertEquals(expResult, result); -242 } -243 -244 /** -245 * Test of addLicense method, of class Model. -246 */ -247 @Test -248 public void testAddLicense() { -249 License license = new License("name", "url"); -250 Model instance = new Model(); -251 instance.addLicense(license); -252 } -253 -254 /** -255 * Test of processProperties method, of class Model. -256 */ -257 @Test -258 public void testProcessProperties() { -259 Properties prop = new Properties(); -260 prop.setProperty("key", "value"); -261 prop.setProperty("nested", "nested ${key}"); -262 String text = "This is a test of '${key}' '${nested}'"; -263 -264 Model instance = new Model(); -265 instance.setName(text); -266 instance.processProperties(prop); -267 String expResults = "This is a test of 'value' 'nested value'"; -268 assertEquals(expResults, instance.getName()); -269 } -270 -271 /** -272 * Test of interpolateString method, of class Model. -273 */ -274 @Test -275 public void testInterpolateString() { -276 Properties prop = new Properties(); -277 prop.setProperty("key", "value"); -278 prop.setProperty("nested", "nested ${key}"); -279 String text = "This is a test of '${key}' '${nested}'"; -280 String expResults = "This is a test of 'value' 'nested value'"; -281 String results = Model.interpolateString(text, prop); -282 assertEquals(expResults, results); -283 } -284 -285 } +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author jeremy +31 */ +32 public class ModelTest extends BaseTest { +33 +34 /** +35 * Test of getName method, of class Model. +36 */ +37 @Test +38 public void testGetName() { +39 Model instance = new Model(); +40 instance.setName(""); +41 String expResult = ""; +42 String result = instance.getName(); +43 assertEquals(expResult, result); +44 } +45 +46 /** +47 * Test of setName method, of class Model. +48 */ +49 @Test +50 public void testSetName() { +51 String name = ""; +52 Model instance = new Model(); +53 instance.setName(name); +54 } +55 +56 /** +57 * Test of getOrganization method, of class Model. +58 */ +59 @Test +60 public void testGetOrganization() { +61 Model instance = new Model(); +62 instance.setOrganization(""); +63 String expResult = ""; +64 String result = instance.getOrganization(); +65 assertEquals(expResult, result); +66 } +67 +68 /** +69 * Test of setOrganization method, of class Model. +70 */ +71 @Test +72 public void testSetOrganization() { +73 String organization = ""; +74 Model instance = new Model(); +75 instance.setOrganization(organization); +76 } +77 +78 /** +79 * Test of getDescription method, of class Model. +80 */ +81 @Test +82 public void testGetDescription() { +83 Model instance = new Model(); +84 instance.setDescription(""); +85 String expResult = ""; +86 String result = instance.getDescription(); +87 assertEquals(expResult, result); +88 } +89 +90 /** +91 * Test of setDescription method, of class Model. +92 */ +93 @Test +94 public void testSetDescription() { +95 String description = ""; +96 Model instance = new Model(); +97 instance.setDescription(description); +98 } +99 +100 /** +101 * Test of getGroupId method, of class Model. +102 */ +103 @Test +104 public void testGetGroupId() { +105 Model instance = new Model(); +106 instance.setGroupId(""); +107 String expResult = ""; +108 String result = instance.getGroupId(); +109 assertEquals(expResult, result); +110 } +111 +112 /** +113 * Test of setGroupId method, of class Model. +114 */ +115 @Test +116 public void testSetGroupId() { +117 String groupId = ""; +118 Model instance = new Model(); +119 instance.setGroupId(groupId); +120 } +121 +122 /** +123 * Test of getArtifactId method, of class Model. +124 */ +125 @Test +126 public void testGetArtifactId() { +127 Model instance = new Model(); +128 instance.setArtifactId(""); +129 String expResult = ""; +130 String result = instance.getArtifactId(); +131 assertEquals(expResult, result); +132 } +133 +134 /** +135 * Test of setArtifactId method, of class Model. +136 */ +137 @Test +138 public void testSetArtifactId() { +139 String artifactId = ""; +140 Model instance = new Model(); +141 instance.setArtifactId(artifactId); +142 } +143 +144 /** +145 * Test of getVersion method, of class Model. +146 */ +147 @Test +148 public void testGetVersion() { +149 Model instance = new Model(); +150 instance.setVersion(""); +151 String expResult = ""; +152 String result = instance.getVersion(); +153 assertEquals(expResult, result); +154 } +155 +156 /** +157 * Test of setVersion method, of class Model. +158 */ +159 @Test +160 public void testSetVersion() { +161 String version = ""; +162 Model instance = new Model(); +163 instance.setVersion(version); +164 } +165 +166 /** +167 * Test of getParentGroupId method, of class Model. +168 */ +169 @Test +170 public void testGetParentGroupId() { +171 Model instance = new Model(); +172 instance.setParentGroupId(""); +173 String expResult = ""; +174 String result = instance.getParentGroupId(); +175 assertEquals(expResult, result); +176 } +177 +178 /** +179 * Test of setParentGroupId method, of class Model. +180 */ +181 @Test +182 public void testSetParentGroupId() { +183 String parentGroupId = ""; +184 Model instance = new Model(); +185 instance.setParentGroupId(parentGroupId); +186 } +187 +188 /** +189 * Test of getParentArtifactId method, of class Model. +190 */ +191 @Test +192 public void testGetParentArtifactId() { +193 Model instance = new Model(); +194 instance.setParentArtifactId(""); +195 String expResult = ""; +196 String result = instance.getParentArtifactId(); +197 assertEquals(expResult, result); +198 } +199 +200 /** +201 * Test of setParentArtifactId method, of class Model. +202 */ +203 @Test +204 public void testSetParentArtifactId() { +205 String parentArtifactId = ""; +206 Model instance = new Model(); +207 instance.setParentArtifactId(parentArtifactId); +208 } +209 +210 /** +211 * Test of getParentVersion method, of class Model. +212 */ +213 @Test +214 public void testGetParentVersion() { +215 Model instance = new Model(); +216 instance.setParentVersion(""); +217 String expResult = ""; +218 String result = instance.getParentVersion(); +219 assertEquals(expResult, result); +220 } +221 +222 /** +223 * Test of setParentVersion method, of class Model. +224 */ +225 @Test +226 public void testSetParentVersion() { +227 String parentVersion = ""; +228 Model instance = new Model(); +229 instance.setParentVersion(parentVersion); +230 } +231 +232 /** +233 * Test of getLicenses method, of class Model. +234 */ +235 @Test +236 public void testGetLicenses() { +237 Model instance = new Model(); +238 instance.addLicense(new License("name", "url")); +239 List<License> expResult = new ArrayList<License>(); +240 expResult.add(new License("name", "url")); +241 List<License> result = instance.getLicenses(); +242 assertEquals(expResult, result); +243 } +244 +245 /** +246 * Test of addLicense method, of class Model. +247 */ +248 @Test +249 public void testAddLicense() { +250 License license = new License("name", "url"); +251 Model instance = new Model(); +252 instance.addLicense(license); +253 } +254 +255 /** +256 * Test of processProperties method, of class Model. +257 */ +258 @Test +259 public void testProcessProperties() { +260 Properties prop = new Properties(); +261 prop.setProperty("key", "value"); +262 prop.setProperty("nested", "nested ${key}"); +263 String text = "This is a test of '${key}' '${nested}'"; +264 +265 Model instance = new Model(); +266 instance.setName(text); +267 instance.processProperties(prop); +268 String expResults = "This is a test of 'value' 'nested value'"; +269 assertEquals(expResults, instance.getName()); +270 } +271 +272 /** +273 * Test of interpolateString method, of class Model. +274 */ +275 @Test +276 public void testInterpolateString() { +277 Properties prop = new Properties(); +278 prop.setProperty("key", "value"); +279 prop.setProperty("nested", "nested ${key}"); +280 String text = "This is a test of '${key}' '${nested}'"; +281 String expResults = "This is a test of 'value' 'nested value'"; +282 String results = Model.interpolateString(text, prop); +283 assertEquals(expResults, results); +284 } +285 +286 }
      diff --git a/xref-test/org/owasp/dependencycheck/xml/pom/PomUtilsTest.html b/xref-test/org/owasp/dependencycheck/xml/pom/PomUtilsTest.html index e7b16a7ec..ee3723757 100644 --- a/xref-test/org/owasp/dependencycheck/xml/pom/PomUtilsTest.html +++ b/xref-test/org/owasp/dependencycheck/xml/pom/PomUtilsTest.html @@ -35,7 +35,7 @@ 27 * 28 * @author jeremy 29 */ -30 public class PomUtilsTest { +30 public class PomUtilsTest extends BaseTest { 31 32 /** 33 * Test of readPom method, of class PomUtils. diff --git a/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html b/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html index ec1840124..efcd96717 100644 --- a/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html b/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html index 0d89526ee..74887e9fd 100644 --- a/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/xref-test/overview-frame.html b/xref-test/overview-frame.html index 389885da2..96a7f5790 100644 --- a/xref-test/overview-frame.html +++ b/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference + Dependency-Check 1.4.0 Reference diff --git a/xref-test/overview-summary.html b/xref-test/overview-summary.html index 9373cdc9a..a2c5bcb63 100644 --- a/xref-test/overview-summary.html +++ b/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference + Dependency-Check 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check 1.3.6 Reference

      +

      Dependency-Check 1.4.0 Reference

      diff --git a/xref/allclasses-frame.html b/xref/allclasses-frame.html index 15a453a60..87b281e17 100644 --- a/xref/allclasses-frame.html +++ b/xref/allclasses-frame.html @@ -214,6 +214,9 @@
    241. ExpectedOjectInputStream +
    242. +
    243. + Experimental
    244. ExtractionException @@ -391,6 +394,9 @@
    245. RubyBundleAuditAnalyzer +
    246. +
    247. + RubyBundlerAnalyzer
    248. RubyGemspecAnalyzer diff --git a/xref/index.html b/xref/index.html index 346723553..b14c5d0a6 100644 --- a/xref/index.html +++ b/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check 1.3.6 Reference + Dependency-Check 1.4.0 Reference diff --git a/xref/org/owasp/dependencycheck/App.html b/xref/org/owasp/dependencycheck/App.html index c85165564..89bed5d8a 100644 --- a/xref/org/owasp/dependencycheck/App.html +++ b/xref/org/owasp/dependencycheck/App.html @@ -288,166 +288,168 @@ 280 final String cveBase12 = cli.getBaseCve12Url(); 281 final String cveBase20 = cli.getBaseCve20Url(); 282 final Integer cveValidForHours = cli.getCveValidForHours(); -283 -284 if (propertiesFile != null) { -285 try { -286 Settings.mergeProperties(propertiesFile); -287 } catch (FileNotFoundException ex) { -288 LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath()); -289 LOGGER.debug("", ex); -290 } catch (IOException ex) { -291 LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath()); -292 LOGGER.debug("", ex); -293 } -294 } -295 // We have to wait until we've merged the properties before attempting to set whether we use -296 // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated -297 // on the command line -298 final boolean nexusUsesProxy = cli.isNexusUsesProxy(); -299 if (dataDirectory != null) { -300 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -301 } else if (System.getProperty("basedir") != null) { -302 final File dataDir = new File(System.getProperty("basedir"), "data"); -303 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -304 } else { -305 final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -306 final File base = jarPath.getParentFile(); -307 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -308 final File dataDir = new File(base, sub); -309 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -310 } -311 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -312 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); -313 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); -314 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser); -315 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass); -316 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -317 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -318 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -319 -320 //File Type Analyzer Settings -321 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); -322 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); -323 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); -324 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled()); -325 Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled()); -326 Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled()); -327 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled()); -328 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled()); -329 Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled()); -330 Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); -331 Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled()); -332 Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled()); -333 Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled()); -334 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled()); -335 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled()); -336 -337 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit()); -338 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -339 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -340 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -341 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -342 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -343 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -344 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -345 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); -346 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -347 if (cveBase12 != null && !cveBase12.isEmpty()) { -348 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12); -349 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20); -350 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12); -351 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20); -352 } -353 } -354 -355 /** -356 * Creates a file appender and adds it to logback. -357 * -358 * @param verboseLog the path to the verbose log file -359 */ -360 private void prepareLogger(String verboseLog) { -361 final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); -362 final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); -363 -364 final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); -365 encoder.setPattern("%d %C:%L%n%-5level - %msg%n"); -366 encoder.setContext(context); -367 encoder.start(); -368 final FileAppender fa = new FileAppender(); -369 fa.setAppend(true); -370 fa.setEncoder(encoder); -371 fa.setContext(context); -372 fa.setFile(verboseLog); -373 final File f = new File(verboseLog); -374 String name = f.getName(); -375 final int i = name.lastIndexOf('.'); -376 if (i > 1) { -377 name = name.substring(0, i); -378 } -379 fa.setName(name); -380 fa.start(); -381 final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); -382 rootLogger.addAppender(fa); -383 } -384 -385 /** -386 * Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style -387 * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first * -388 * or ?). -389 * -390 * @param path the path to canonicalize -391 * @return the canonical path -392 */ -393 protected String ensureCanonicalPath(String path) { -394 String basePath = null; -395 String wildCards = null; -396 final String file = path.replace('\\', '/'); -397 if (file.contains("*") || file.contains("?")) { -398 -399 int pos = getLastFileSeparator(file); -400 if (pos < 0) { -401 return file; -402 } -403 pos += 1; -404 basePath = file.substring(0, pos); -405 wildCards = file.substring(pos); -406 } else { -407 basePath = file; -408 } -409 -410 File f = new File(basePath); -411 try { -412 f = f.getCanonicalFile(); -413 if (wildCards != null) { -414 f = new File(f, wildCards); -415 } -416 } catch (IOException ex) { -417 LOGGER.warn("Invalid path '{}' was provided.", path); -418 LOGGER.debug("Invalid path provided", ex); -419 } -420 return f.getAbsolutePath().replace('\\', '/'); -421 } -422 -423 /** -424 * Returns the position of the last file separator. -425 * -426 * @param file a file path -427 * @return the position of the last file separator -428 */ -429 private int getLastFileSeparator(String file) { -430 if (file.contains("*") || file.contains("?")) { -431 int p1 = file.indexOf('*'); -432 int p2 = file.indexOf('?'); -433 p1 = p1 > 0 ? p1 : file.length(); -434 p2 = p2 > 0 ? p2 : file.length(); -435 int pos = p1 < p2 ? p1 : p2; -436 pos = file.lastIndexOf('/', pos); -437 return pos; -438 } else { -439 return file.lastIndexOf('/'); -440 } -441 } -442 } +283 final boolean experimentalEnabled = cli.isExperimentalEnabled(); +284 +285 if (propertiesFile != null) { +286 try { +287 Settings.mergeProperties(propertiesFile); +288 } catch (FileNotFoundException ex) { +289 LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath()); +290 LOGGER.debug("", ex); +291 } catch (IOException ex) { +292 LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath()); +293 LOGGER.debug("", ex); +294 } +295 } +296 // We have to wait until we've merged the properties before attempting to set whether we use +297 // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated +298 // on the command line +299 final boolean nexusUsesProxy = cli.isNexusUsesProxy(); +300 if (dataDirectory != null) { +301 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +302 } else if (System.getProperty("basedir") != null) { +303 final File dataDir = new File(System.getProperty("basedir"), "data"); +304 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +305 } else { +306 final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +307 final File base = jarPath.getParentFile(); +308 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +309 final File dataDir = new File(base, sub); +310 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +311 } +312 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +313 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); +314 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); +315 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser); +316 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass); +317 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +318 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +319 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +320 +321 //File Type Analyzer Settings +322 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled); +323 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); +324 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); +325 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); +326 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled()); +327 Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled()); +328 Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled()); +329 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled()); +330 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled()); +331 Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled()); +332 Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); +333 Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled()); +334 Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled()); +335 Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled()); +336 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled()); +337 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled()); +338 +339 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit()); +340 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +341 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +342 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +343 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +344 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +345 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +346 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +347 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); +348 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +349 if (cveBase12 != null && !cveBase12.isEmpty()) { +350 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12); +351 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20); +352 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12); +353 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20); +354 } +355 } +356 +357 /** +358 * Creates a file appender and adds it to logback. +359 * +360 * @param verboseLog the path to the verbose log file +361 */ +362 private void prepareLogger(String verboseLog) { +363 final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); +364 final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); +365 +366 final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); +367 encoder.setPattern("%d %C:%L%n%-5level - %msg%n"); +368 encoder.setContext(context); +369 encoder.start(); +370 final FileAppender fa = new FileAppender(); +371 fa.setAppend(true); +372 fa.setEncoder(encoder); +373 fa.setContext(context); +374 fa.setFile(verboseLog); +375 final File f = new File(verboseLog); +376 String name = f.getName(); +377 final int i = name.lastIndexOf('.'); +378 if (i > 1) { +379 name = name.substring(0, i); +380 } +381 fa.setName(name); +382 fa.start(); +383 final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); +384 rootLogger.addAppender(fa); +385 } +386 +387 /** +388 * Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style +389 * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first * +390 * or ?). +391 * +392 * @param path the path to canonicalize +393 * @return the canonical path +394 */ +395 protected String ensureCanonicalPath(String path) { +396 String basePath = null; +397 String wildCards = null; +398 final String file = path.replace('\\', '/'); +399 if (file.contains("*") || file.contains("?")) { +400 +401 int pos = getLastFileSeparator(file); +402 if (pos < 0) { +403 return file; +404 } +405 pos += 1; +406 basePath = file.substring(0, pos); +407 wildCards = file.substring(pos); +408 } else { +409 basePath = file; +410 } +411 +412 File f = new File(basePath); +413 try { +414 f = f.getCanonicalFile(); +415 if (wildCards != null) { +416 f = new File(f, wildCards); +417 } +418 } catch (IOException ex) { +419 LOGGER.warn("Invalid path '{}' was provided.", path); +420 LOGGER.debug("Invalid path provided", ex); +421 } +422 return f.getAbsolutePath().replace('\\', '/'); +423 } +424 +425 /** +426 * Returns the position of the last file separator. +427 * +428 * @param file a file path +429 * @return the position of the last file separator +430 */ +431 private int getLastFileSeparator(String file) { +432 if (file.contains("*") || file.contains("?")) { +433 int p1 = file.indexOf('*'); +434 int p2 = file.indexOf('?'); +435 p1 = p1 > 0 ? p1 : file.length(); +436 p2 = p2 > 0 ? p2 : file.length(); +437 int pos = p1 < p2 ? p1 : p2; +438 pos = file.lastIndexOf('/', pos); +439 return pos; +440 } else { +441 return file.lastIndexOf('/'); +442 } +443 } +444 }
      diff --git a/xref/org/owasp/dependencycheck/CliParser.html b/xref/org/owasp/dependencycheck/CliParser.html index a03826056..3305f4a91 100644 --- a/xref/org/owasp/dependencycheck/CliParser.html +++ b/xref/org/owasp/dependencycheck/CliParser.html @@ -66,1248 +66,1335 @@ 58 * Parses the arguments passed in and captures the results for later use. 59 * 60 * @param args the command line arguments -61 * @throws FileNotFoundException is thrown when a 'file' argument does not point to a file that exists. -62 * @throws ParseException is thrown when a Parse Exception occurs. -63 */ -64 public void parse(String[] args) throws FileNotFoundException, ParseException { -65 line = parseArgs(args); -66 -67 if (line != null) { -68 validateArgs(); -69 } -70 } -71 -72 /** -73 * Parses the command line arguments. -74 * -75 * @param args the command line arguments -76 * @return the results of parsing the command line arguments -77 * @throws ParseException if the arguments are invalid -78 */ -79 private CommandLine parseArgs(String[] args) throws ParseException { -80 final CommandLineParser parser = new DefaultParser(); -81 final Options options = createCommandLineOptions(); -82 return parser.parse(options, args); -83 } -84 -85 /** -86 * Validates that the command line arguments are valid. -87 * -88 * @throws FileNotFoundException if there is a file specified by either the SCAN or CPE command line arguments that does not -89 * exist. -90 * @throws ParseException is thrown if there is an exception parsing the command line. -91 */ -92 private void validateArgs() throws FileNotFoundException, ParseException { -93 if (isUpdateOnly() || isRunScan()) { -94 final String value = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS); -95 if (value != null) { -96 try { -97 final int i = Integer.parseInt(value); -98 if (i < 0) { -99 throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0."); -100 } -101 } catch (NumberFormatException ex) { -102 throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0."); -103 } -104 } -105 } -106 if (isRunScan()) { -107 validatePathExists(getScanFiles(), ARGUMENT.SCAN); -108 validatePathExists(getReportDirectory(), ARGUMENT.OUT); -109 if (getPathToMono() != null) { -110 validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO); -111 } -112 if (!line.hasOption(ARGUMENT.APP_NAME) && !line.hasOption(ARGUMENT.PROJECT)) { -113 throw new ParseException("Missing '" + ARGUMENT.PROJECT + "' argument; the scan cannot be run without the an project name."); -114 } -115 if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) { -116 final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT); -117 try { -118 Format.valueOf(format); -119 } catch (IllegalArgumentException ex) { -120 final String msg = String.format("An invalid 'format' of '%s' was specified. " -121 + "Supported output formats are XML, HTML, VULN, or ALL", format); -122 throw new ParseException(msg); -123 } -124 } -125 if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null) -126 && (getBaseCve12Url() == null || getBaseCve20Url() == null || getModifiedCve12Url() == null || getModifiedCve20Url() == null)) { -127 final String msg = "If one of the CVE URLs is specified they must all be specified; please add the missing CVE URL."; -128 throw new ParseException(msg); -129 } -130 if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) { -131 try { -132 final int i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH)); -133 if (i < 0) { -134 throw new ParseException("Symbolic Link Depth (symLink) must be greater than zero."); -135 } -136 } catch (NumberFormatException ex) { -137 throw new ParseException("Symbolic Link Depth (symLink) is not a number."); -138 } -139 } -140 } -141 } -142 -143 /** -144 * Validates whether or not the path(s) points at a file that exists; if the path(s) does not point to an existing file a -145 * FileNotFoundException is thrown. -146 * -147 * @param paths the paths to validate if they exists -148 * @param optType the option being validated (e.g. scan, out, etc.) -149 * @throws FileNotFoundException is thrown if one of the paths being validated does not exist. -150 */ -151 private void validatePathExists(String[] paths, String optType) throws FileNotFoundException { -152 for (String path : paths) { -153 validatePathExists(path, optType); -154 } -155 } -156 -157 /** -158 * Validates whether or not the path points at a file that exists; if the path does not point to an existing file a -159 * FileNotFoundException is thrown. -160 * -161 * @param path the paths to validate if they exists -162 * @param argumentName the argument being validated (e.g. scan, out, etc.) -163 * @throws FileNotFoundException is thrown if the path being validated does not exist. -164 */ -165 private void validatePathExists(String path, String argumentName) throws FileNotFoundException { -166 if (path == null) { -167 isValid = false; -168 final String msg = String.format("Invalid '%s' argument: null", argumentName); -169 throw new FileNotFoundException(msg); -170 } else if (!path.contains("*") && !path.contains("?")) { -171 File f = new File(path); -172 if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) { -173 final String checkPath = path.toLowerCase(); -174 if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) { -175 if (f.getParentFile() == null) { -176 f = new File(".", path); -177 } -178 if (!f.getParentFile().isDirectory()) { -179 isValid = false; -180 final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); -181 throw new FileNotFoundException(msg); -182 } -183 } -184 } else { -185 if (!f.exists()) { -186 isValid = false; -187 final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); -188 throw new FileNotFoundException(msg); +61 * @throws FileNotFoundException is thrown when a 'file' argument does not +62 * point to a file that exists. +63 * @throws ParseException is thrown when a Parse Exception occurs. +64 */ +65 public void parse(String[] args) throws FileNotFoundException, ParseException { +66 line = parseArgs(args); +67 +68 if (line != null) { +69 validateArgs(); +70 } +71 } +72 +73 /** +74 * Parses the command line arguments. +75 * +76 * @param args the command line arguments +77 * @return the results of parsing the command line arguments +78 * @throws ParseException if the arguments are invalid +79 */ +80 private CommandLine parseArgs(String[] args) throws ParseException { +81 final CommandLineParser parser = new DefaultParser(); +82 final Options options = createCommandLineOptions(); +83 return parser.parse(options, args); +84 } +85 +86 /** +87 * Validates that the command line arguments are valid. +88 * +89 * @throws FileNotFoundException if there is a file specified by either the +90 * SCAN or CPE command line arguments that does not exist. +91 * @throws ParseException is thrown if there is an exception parsing the +92 * command line. +93 */ +94 private void validateArgs() throws FileNotFoundException, ParseException { +95 if (isUpdateOnly() || isRunScan()) { +96 final String value = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS); +97 if (value != null) { +98 try { +99 final int i = Integer.parseInt(value); +100 if (i < 0) { +101 throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0."); +102 } +103 } catch (NumberFormatException ex) { +104 throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0."); +105 } +106 } +107 } +108 if (isRunScan()) { +109 validatePathExists(getScanFiles(), ARGUMENT.SCAN); +110 validatePathExists(getReportDirectory(), ARGUMENT.OUT); +111 if (getPathToMono() != null) { +112 validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO); +113 } +114 if (!line.hasOption(ARGUMENT.APP_NAME) && !line.hasOption(ARGUMENT.PROJECT)) { +115 throw new ParseException("Missing '" + ARGUMENT.PROJECT + "' argument; the scan cannot be run without the an project name."); +116 } +117 if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) { +118 final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT); +119 try { +120 Format.valueOf(format); +121 } catch (IllegalArgumentException ex) { +122 final String msg = String.format("An invalid 'format' of '%s' was specified. " +123 + "Supported output formats are XML, HTML, VULN, or ALL", format); +124 throw new ParseException(msg); +125 } +126 } +127 if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null) +128 && (getBaseCve12Url() == null || getBaseCve20Url() == null || getModifiedCve12Url() == null || getModifiedCve20Url() == null)) { +129 final String msg = "If one of the CVE URLs is specified they must all be specified; please add the missing CVE URL."; +130 throw new ParseException(msg); +131 } +132 if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) { +133 try { +134 final int i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH)); +135 if (i < 0) { +136 throw new ParseException("Symbolic Link Depth (symLink) must be greater than zero."); +137 } +138 } catch (NumberFormatException ex) { +139 throw new ParseException("Symbolic Link Depth (symLink) is not a number."); +140 } +141 } +142 } +143 } +144 +145 /** +146 * Validates whether or not the path(s) points at a file that exists; if the +147 * path(s) does not point to an existing file a FileNotFoundException is +148 * thrown. +149 * +150 * @param paths the paths to validate if they exists +151 * @param optType the option being validated (e.g. scan, out, etc.) +152 * @throws FileNotFoundException is thrown if one of the paths being +153 * validated does not exist. +154 */ +155 private void validatePathExists(String[] paths, String optType) throws FileNotFoundException { +156 for (String path : paths) { +157 validatePathExists(path, optType); +158 } +159 } +160 +161 /** +162 * Validates whether or not the path points at a file that exists; if the +163 * path does not point to an existing file a FileNotFoundException is +164 * thrown. +165 * +166 * @param path the paths to validate if they exists +167 * @param argumentName the argument being validated (e.g. scan, out, etc.) +168 * @throws FileNotFoundException is thrown if the path being validated does +169 * not exist. +170 */ +171 private void validatePathExists(String path, String argumentName) throws FileNotFoundException { +172 if (path == null) { +173 isValid = false; +174 final String msg = String.format("Invalid '%s' argument: null", argumentName); +175 throw new FileNotFoundException(msg); +176 } else if (!path.contains("*") && !path.contains("?")) { +177 File f = new File(path); +178 if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) { +179 final String checkPath = path.toLowerCase(); +180 if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) { +181 if (f.getParentFile() == null) { +182 f = new File(".", path); +183 } +184 if (!f.getParentFile().isDirectory()) { +185 isValid = false; +186 final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); +187 throw new FileNotFoundException(msg); +188 } 189 } -190 } -191 } else if (path.startsWith("//") || path.startsWith("\\\\")) { -192 isValid = false; -193 final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path); -194 throw new FileNotFoundException(msg); -195 } -196 } -197 -198 /** -199 * Generates an Options collection that is used to parse the command line and to display the help message. -200 * -201 * @return the command line options used for parsing the command line -202 */ -203 @SuppressWarnings("static-access") -204 private Options createCommandLineOptions() { -205 final Options options = new Options(); -206 addStandardOptions(options); -207 addAdvancedOptions(options); -208 addDeprecatedOptions(options); -209 return options; -210 } -211 -212 /** -213 * Adds the standard command line options to the given options collection. -214 * -215 * @param options a collection of command line arguments -216 * @throws IllegalArgumentException thrown if there is an exception -217 */ -218 @SuppressWarnings("static-access") -219 private void addStandardOptions(final Options options) throws IllegalArgumentException { -220 final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false, -221 "Print this message."); -222 -223 final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP) -224 .desc("Print the advanced help message.").build(); -225 -226 final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION, -227 false, "Print the version information."); -228 -229 final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE, -230 false, "Disables the automatic updating of the CPE data."); -231 -232 final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT) -233 .desc("The name of the project being scanned. This is a required argument.") -234 .build(); -235 -236 final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN) -237 .desc("The path to scan - this option can be specified multiple times. Ant style" -238 + " paths are supported (e.g. path/**/*.jar).") +190 } else if (!f.exists()) { +191 isValid = false; +192 final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); +193 throw new FileNotFoundException(msg); +194 } +195 } else if (path.startsWith("//") || path.startsWith("\\\\")) { +196 isValid = false; +197 final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path); +198 throw new FileNotFoundException(msg); +199 } +200 } +201 +202 /** +203 * Generates an Options collection that is used to parse the command line +204 * and to display the help message. +205 * +206 * @return the command line options used for parsing the command line +207 */ +208 @SuppressWarnings("static-access") +209 private Options createCommandLineOptions() { +210 final Options options = new Options(); +211 addStandardOptions(options); +212 addAdvancedOptions(options); +213 addDeprecatedOptions(options); +214 return options; +215 } +216 +217 /** +218 * Adds the standard command line options to the given options collection. +219 * +220 * @param options a collection of command line arguments +221 * @throws IllegalArgumentException thrown if there is an exception +222 */ +223 @SuppressWarnings("static-access") +224 private void addStandardOptions(final Options options) throws IllegalArgumentException { +225 final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false, +226 "Print this message."); +227 +228 final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP) +229 .desc("Print the advanced help message.").build(); +230 +231 final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION, +232 false, "Print the version information."); +233 +234 final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE, +235 false, "Disables the automatic updating of the CPE data."); +236 +237 final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT) +238 .desc("The name of the project being scanned. This is a required argument.") 239 .build(); 240 -241 final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE) -242 .desc("Specify and exclusion pattern. This option can be specified multiple times" -243 + " and it accepts Ant style excludsions.") +241 final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN) +242 .desc("The path to scan - this option can be specified multiple times. Ant style" +243 + " paths are supported (e.g. path/**/*.jar).") 244 .build(); 245 -246 final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP) -247 .desc("A property file to load.") -248 .build(); -249 -250 final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT) -251 .desc("The folder to write reports to. This defaults to the current directory. " -252 + "It is possible to set this to a specific file name if the format argument is not set to ALL.") +246 final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE) +247 .desc("Specify and exclusion pattern. This option can be specified multiple times" +248 + " and it accepts Ant style excludsions.") +249 .build(); +250 +251 final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP) +252 .desc("A property file to load.") 253 .build(); 254 -255 final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT) -256 .desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.") -257 .build(); -258 -259 final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG) -260 .desc("The file path to write verbose logging information.") -261 .build(); -262 -263 final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH) -264 .desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.") -265 .build(); -266 -267 final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE) -268 .desc("The file path to the suppression XML file.") -269 .build(); -270 -271 final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS) -272 .desc("The number of hours to wait before checking for new updates from the NVD.") -273 .build(); -274 -275 //This is an option group because it can be specified more then once. -276 final OptionGroup og = new OptionGroup(); -277 og.addOption(path); -278 -279 final OptionGroup exog = new OptionGroup(); -280 exog.addOption(excludes); -281 -282 options.addOptionGroup(og) -283 .addOptionGroup(exog) -284 .addOption(projectName) -285 .addOption(out) -286 .addOption(outputFormat) -287 .addOption(version) -288 .addOption(help) -289 .addOption(advancedHelp) -290 .addOption(noUpdate) -291 .addOption(symLinkDepth) -292 .addOption(props) -293 .addOption(verboseLog) -294 .addOption(suppressionFile) -295 .addOption(cveValidForHours); -296 } -297 -298 /** -299 * Adds the advanced command line options to the given options collection. These are split out for purposes of being able to -300 * display two different help messages. -301 * -302 * @param options a collection of command line arguments -303 * @throws IllegalArgumentException thrown if there is an exception -304 */ -305 @SuppressWarnings("static-access") -306 private void addAdvancedOptions(final Options options) throws IllegalArgumentException { +255 final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT) +256 .desc("The folder to write reports to. This defaults to the current directory. " +257 + "It is possible to set this to a specific file name if the format argument is not set to ALL.") +258 .build(); +259 +260 final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT) +261 .desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.") +262 .build(); +263 +264 final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG) +265 .desc("The file path to write verbose logging information.") +266 .build(); +267 +268 final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH) +269 .desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.") +270 .build(); +271 +272 final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE) +273 .desc("The file path to the suppression XML file.") +274 .build(); +275 +276 final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS) +277 .desc("The number of hours to wait before checking for new updates from the NVD.") +278 .build(); +279 +280 final Option experimentalEnabled = Option.builder().longOpt(ARGUMENT.EXPERIMENTAL) +281 .desc("Enables the experimental analzers.") +282 .build(); +283 +284 //This is an option group because it can be specified more then once. +285 final OptionGroup og = new OptionGroup(); +286 og.addOption(path); +287 +288 final OptionGroup exog = new OptionGroup(); +289 exog.addOption(excludes); +290 +291 options.addOptionGroup(og) +292 .addOptionGroup(exog) +293 .addOption(projectName) +294 .addOption(out) +295 .addOption(outputFormat) +296 .addOption(version) +297 .addOption(help) +298 .addOption(advancedHelp) +299 .addOption(noUpdate) +300 .addOption(symLinkDepth) +301 .addOption(props) +302 .addOption(verboseLog) +303 .addOption(suppressionFile) +304 .addOption(cveValidForHours) +305 .addOption(experimentalEnabled); +306 } 307 -308 final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12) -309 .desc("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ") -310 .build(); -311 -312 final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20) -313 .desc("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.") -314 .build(); -315 -316 final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12) -317 .desc("URL for the modified CVE 1.2.") -318 .build(); -319 -320 final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20) -321 .desc("URL for the modified CVE 2.0.") -322 .build(); -323 -324 final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY) -325 .desc("Only update the local NVD data cache; no scan will be executed.").build(); +308 /** +309 * Adds the advanced command line options to the given options collection. +310 * These are split out for purposes of being able to display two different +311 * help messages. +312 * +313 * @param options a collection of command line arguments +314 * @throws IllegalArgumentException thrown if there is an exception +315 */ +316 @SuppressWarnings("static-access") +317 private void addAdvancedOptions(final Options options) throws IllegalArgumentException { +318 +319 final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12) +320 .desc("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ") +321 .build(); +322 +323 final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20) +324 .desc("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.") +325 .build(); 326 -327 final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY) -328 .desc("The location of the H2 Database file. This option should generally not be set.") +327 final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12) +328 .desc("URL for the modified CVE 1.2.") 329 .build(); 330 -331 final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL) -332 .desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). " -333 + "If not set the Nexus Analyzer will be disabled.").build(); +331 final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20) +332 .desc("URL for the modified CVE 2.0.") +333 .build(); 334 -335 final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY) -336 .desc("Whether or not the configured proxy should be used when connecting to Nexus.") -337 .build(); -338 -339 final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg() -340 .longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS) -341 .desc("A comma separated list of additional extensions to be scanned as ZIP files " -342 + "(ZIP, EAR, WAR are already treated as zip files)").build(); -343 -344 final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO) -345 .desc("The path to Mono for .NET Assembly analysis on non-windows systems.") -346 .build(); -347 -348 final Option pathToBundleAudit = Option.builder().argName("path").hasArg() -349 .longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT) -350 .desc("The path to bundle-audit for Gem bundle analysis.").build(); -351 -352 final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg() -353 .longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.") -354 .build(); -355 -356 final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER) -357 .desc("The proxy server to use when downloading resources.").build(); +335 final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY) +336 .desc("Only update the local NVD data cache; no scan will be executed.").build(); +337 +338 final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY) +339 .desc("The location of the H2 Database file. This option should generally not be set.") +340 .build(); +341 +342 final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL) +343 .desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). " +344 + "If not set the Nexus Analyzer will be disabled.").build(); +345 +346 final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY) +347 .desc("Whether or not the configured proxy should be used when connecting to Nexus.") +348 .build(); +349 +350 final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg() +351 .longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS) +352 .desc("A comma separated list of additional extensions to be scanned as ZIP files " +353 + "(ZIP, EAR, WAR are already treated as zip files)").build(); +354 +355 final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO) +356 .desc("The path to Mono for .NET Assembly analysis on non-windows systems.") +357 .build(); 358 -359 final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT) -360 .desc("The proxy port to use when downloading resources.").build(); -361 -362 final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME) -363 .desc("The proxy username to use when downloading resources.").build(); -364 -365 final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD) -366 .desc("The proxy password to use when downloading resources.").build(); -367 -368 final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING) -369 .desc("The connection string to the database.").build(); -370 -371 final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME) -372 .desc("The username used to connect to the database.").build(); -373 -374 final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD) -375 .desc("The password for connecting to the database.").build(); -376 -377 final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER) -378 .desc("The database driver name.").build(); -379 -380 final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH) -381 .desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.") -382 .build(); -383 -384 final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR) -385 .desc("Disable the Jar Analyzer.").build(); -386 -387 final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE) -388 .desc("Disable the Archive Analyzer.").build(); -389 -390 final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC) -391 .desc("Disable the Nuspec Analyzer.").build(); -392 -393 final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY) -394 .desc("Disable the .NET Assembly Analyzer.").build(); -395 -396 final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST) -397 .desc("Disable the Python Distribution Analyzer.").build(); -398 -399 final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG) -400 .desc("Disable the Python Package Analyzer.").build(); -401 -402 final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER) -403 .desc("Disable the PHP Composer Analyzer.").build(); -404 -405 final Option disableAutoconfAnalyzer = Option.builder() -406 .longOpt(ARGUMENT.DISABLE_AUTOCONF) -407 .desc("Disable the Autoconf Analyzer.").build(); -408 -409 final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL) -410 .desc("Disable the OpenSSL Analyzer.").build(); -411 final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE) -412 .desc("Disable the Cmake Analyzer.").build(); -413 -414 final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL) -415 .desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable " -416 + "the Nexus Analyzer.").build(); -417 -418 final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS) -419 .desc("Disable the Nexus Analyzer.").build(); -420 -421 final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD) -422 .desc("Purges the local NVD data cache") -423 .build(); +359 final Option pathToBundleAudit = Option.builder().argName("path").hasArg() +360 .longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT) +361 .desc("The path to bundle-audit for Gem bundle analysis.").build(); +362 +363 final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg() +364 .longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.") +365 .build(); +366 +367 final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER) +368 .desc("The proxy server to use when downloading resources.").build(); +369 +370 final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT) +371 .desc("The proxy port to use when downloading resources.").build(); +372 +373 final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME) +374 .desc("The proxy username to use when downloading resources.").build(); +375 +376 final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD) +377 .desc("The proxy password to use when downloading resources.").build(); +378 +379 final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING) +380 .desc("The connection string to the database.").build(); +381 +382 final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME) +383 .desc("The username used to connect to the database.").build(); +384 +385 final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD) +386 .desc("The password for connecting to the database.").build(); +387 +388 final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER) +389 .desc("The database driver name.").build(); +390 +391 final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH) +392 .desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.") +393 .build(); +394 +395 final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR) +396 .desc("Disable the Jar Analyzer.").build(); +397 +398 final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE) +399 .desc("Disable the Archive Analyzer.").build(); +400 +401 final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC) +402 .desc("Disable the Nuspec Analyzer.").build(); +403 +404 final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY) +405 .desc("Disable the .NET Assembly Analyzer.").build(); +406 +407 final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST) +408 .desc("Disable the Python Distribution Analyzer.").build(); +409 +410 final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG) +411 .desc("Disable the Python Package Analyzer.").build(); +412 +413 final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER) +414 .desc("Disable the PHP Composer Analyzer.").build(); +415 +416 final Option disableAutoconfAnalyzer = Option.builder() +417 .longOpt(ARGUMENT.DISABLE_AUTOCONF) +418 .desc("Disable the Autoconf Analyzer.").build(); +419 +420 final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL) +421 .desc("Disable the OpenSSL Analyzer.").build(); +422 final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE) +423 .desc("Disable the Cmake Analyzer.").build(); 424 -425 options.addOption(updateOnly) -426 .addOption(cve12Base) -427 .addOption(cve20Base) -428 .addOption(cve12Modified) -429 .addOption(cve20Modified) -430 .addOption(proxyPort) -431 .addOption(proxyServer) -432 .addOption(proxyUsername) -433 .addOption(proxyPassword) -434 .addOption(connectionTimeout) -435 .addOption(connectionString) -436 .addOption(dbUser) -437 .addOption(data) -438 .addOption(dbPassword) -439 .addOption(dbDriver) -440 .addOption(dbDriverPath) -441 .addOption(disableJarAnalyzer) -442 .addOption(disableArchiveAnalyzer) -443 .addOption(disableAssemblyAnalyzer) -444 .addOption(pathToBundleAudit) -445 .addOption(disablePythonDistributionAnalyzer) -446 .addOption(disableCmakeAnalyzer) -447 .addOption(disablePythonPackageAnalyzer) -448 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS) -449 .desc("Disable the Ruby Gemspec Analyzer.").build()) -450 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT) -451 .desc("Disable the Ruby Bundler-Audit Analyzer.").build()) -452 .addOption(disableAutoconfAnalyzer) -453 .addOption(disableComposerAnalyzer) -454 .addOption(disableOpenSSLAnalyzer) -455 .addOption(disableNuspecAnalyzer) -456 .addOption(disableCentralAnalyzer) -457 .addOption(disableNexusAnalyzer) -458 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS) -459 .desc("Disable the Node.js Package Analyzer.").build()) -460 .addOption(nexusUrl) -461 .addOption(nexusUsesProxy) -462 .addOption(additionalZipExtensions) -463 .addOption(pathToMono) -464 .addOption(pathToBundleAudit) -465 .addOption(purge); -466 } -467 -468 /** -469 * Adds the deprecated command line options to the given options collection. These are split out for purposes of not including -470 * them in the help message. We need to add the deprecated options so as not to break existing scripts. -471 * -472 * @param options a collection of command line arguments -473 * @throws IllegalArgumentException thrown if there is an exception -474 */ -475 @SuppressWarnings({"static-access", "deprecation"}) -476 private void addDeprecatedOptions(final Options options) throws IllegalArgumentException { -477 -478 final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL) -479 .desc("The proxy url argument is deprecated, use proxyserver instead.") -480 .build(); -481 final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME) -482 .desc("The name of the project being scanned.") -483 .build(); -484 -485 options.addOption(proxyServer); -486 options.addOption(appName); -487 } -488 -489 /** -490 * Determines if the 'version' command line argument was passed in. -491 * -492 * @return whether or not the 'version' command line argument was passed in -493 */ -494 public boolean isGetVersion() { -495 return (line != null) && line.hasOption(ARGUMENT.VERSION); -496 } +425 final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL) +426 .desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable " +427 + "the Nexus Analyzer.").build(); +428 +429 final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS) +430 .desc("Disable the Nexus Analyzer.").build(); +431 +432 final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD) +433 .desc("Purges the local NVD data cache") +434 .build(); +435 +436 options.addOption(updateOnly) +437 .addOption(cve12Base) +438 .addOption(cve20Base) +439 .addOption(cve12Modified) +440 .addOption(cve20Modified) +441 .addOption(proxyPort) +442 .addOption(proxyServer) +443 .addOption(proxyUsername) +444 .addOption(proxyPassword) +445 .addOption(connectionTimeout) +446 .addOption(connectionString) +447 .addOption(dbUser) +448 .addOption(data) +449 .addOption(dbPassword) +450 .addOption(dbDriver) +451 .addOption(dbDriverPath) +452 .addOption(disableJarAnalyzer) +453 .addOption(disableArchiveAnalyzer) +454 .addOption(disableAssemblyAnalyzer) +455 .addOption(pathToBundleAudit) +456 .addOption(disablePythonDistributionAnalyzer) +457 .addOption(disableCmakeAnalyzer) +458 .addOption(disablePythonPackageAnalyzer) +459 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS) +460 .desc("Disable the Ruby Gemspec Analyzer.").build()) +461 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT) +462 .desc("Disable the Ruby Bundler-Audit Analyzer.").build()) +463 .addOption(disableAutoconfAnalyzer) +464 .addOption(disableComposerAnalyzer) +465 .addOption(disableOpenSSLAnalyzer) +466 .addOption(disableNuspecAnalyzer) +467 .addOption(disableCentralAnalyzer) +468 .addOption(disableNexusAnalyzer) +469 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS) +470 .desc("Disable the Node.js Package Analyzer.").build()) +471 .addOption(nexusUrl) +472 .addOption(nexusUsesProxy) +473 .addOption(additionalZipExtensions) +474 .addOption(pathToMono) +475 .addOption(pathToBundleAudit) +476 .addOption(purge); +477 } +478 +479 /** +480 * Adds the deprecated command line options to the given options collection. +481 * These are split out for purposes of not including them in the help +482 * message. We need to add the deprecated options so as not to break +483 * existing scripts. +484 * +485 * @param options a collection of command line arguments +486 * @throws IllegalArgumentException thrown if there is an exception +487 */ +488 @SuppressWarnings({"static-access", "deprecation"}) +489 private void addDeprecatedOptions(final Options options) throws IllegalArgumentException { +490 +491 final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL) +492 .desc("The proxy url argument is deprecated, use proxyserver instead.") +493 .build(); +494 final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME) +495 .desc("The name of the project being scanned.") +496 .build(); 497 -498 /** -499 * Determines if the 'help' command line argument was passed in. -500 * -501 * @return whether or not the 'help' command line argument was passed in -502 */ -503 public boolean isGetHelp() { -504 return (line != null) && line.hasOption(ARGUMENT.HELP); -505 } -506 -507 /** -508 * Determines if the 'scan' command line argument was passed in. -509 * -510 * @return whether or not the 'scan' command line argument was passed in -511 */ -512 public boolean isRunScan() { -513 return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN); -514 } -515 -516 /** -517 * Returns the symbolic link depth (how deeply symbolic links will be followed). -518 * -519 * @return the symbolic link depth -520 */ -521 public int getSymLinkDepth() { -522 int value = 0; -523 try { -524 value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0")); -525 if (value < 0) { -526 value = 0; -527 } -528 } catch (NumberFormatException ex) { -529 LOGGER.debug("Symbolic link was not a number"); -530 } -531 return value; -532 } -533 -534 /** -535 * Returns true if the disableJar command line argument was specified. -536 * -537 * @return true if the disableJar command line argument was specified; otherwise false -538 */ -539 public boolean isJarDisabled() { -540 return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR); -541 } -542 -543 /** -544 * Returns true if the disableArchive command line argument was specified. -545 * -546 * @return true if the disableArchive command line argument was specified; otherwise false -547 */ -548 public boolean isArchiveDisabled() { -549 return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE); -550 } -551 -552 /** -553 * Returns true if the disableNuspec command line argument was specified. -554 * -555 * @return true if the disableNuspec command line argument was specified; otherwise false -556 */ -557 public boolean isNuspecDisabled() { -558 return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC); -559 } -560 -561 /** -562 * Returns true if the disableAssembly command line argument was specified. -563 * -564 * @return true if the disableAssembly command line argument was specified; otherwise false -565 */ -566 public boolean isAssemblyDisabled() { -567 return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY); -568 } -569 -570 /** -571 * Returns true if the disableBundleAudit command line argument was specified. -572 * -573 * @return true if the disableBundleAudit command line argument was specified; otherwise false -574 */ -575 public boolean isBundleAuditDisabled() { -576 return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT); -577 } -578 -579 /** -580 * Returns true if the disablePyDist command line argument was specified. -581 * -582 * @return true if the disablePyDist command line argument was specified; otherwise false +498 options.addOption(proxyServer); +499 options.addOption(appName); +500 } +501 +502 /** +503 * Determines if the 'version' command line argument was passed in. +504 * +505 * @return whether or not the 'version' command line argument was passed in +506 */ +507 public boolean isGetVersion() { +508 return (line != null) && line.hasOption(ARGUMENT.VERSION); +509 } +510 +511 /** +512 * Determines if the 'help' command line argument was passed in. +513 * +514 * @return whether or not the 'help' command line argument was passed in +515 */ +516 public boolean isGetHelp() { +517 return (line != null) && line.hasOption(ARGUMENT.HELP); +518 } +519 +520 /** +521 * Determines if the 'scan' command line argument was passed in. +522 * +523 * @return whether or not the 'scan' command line argument was passed in +524 */ +525 public boolean isRunScan() { +526 return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN); +527 } +528 +529 /** +530 * Returns the symbolic link depth (how deeply symbolic links will be +531 * followed). +532 * +533 * @return the symbolic link depth +534 */ +535 public int getSymLinkDepth() { +536 int value = 0; +537 try { +538 value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0")); +539 if (value < 0) { +540 value = 0; +541 } +542 } catch (NumberFormatException ex) { +543 LOGGER.debug("Symbolic link was not a number"); +544 } +545 return value; +546 } +547 +548 /** +549 * Returns true if the disableJar command line argument was specified. +550 * +551 * @return true if the disableJar command line argument was specified; +552 * otherwise false +553 */ +554 public boolean isJarDisabled() { +555 return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR); +556 } +557 +558 /** +559 * Returns true if the disableArchive command line argument was specified. +560 * +561 * @return true if the disableArchive command line argument was specified; +562 * otherwise false +563 */ +564 public boolean isArchiveDisabled() { +565 return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE); +566 } +567 +568 /** +569 * Returns true if the disableNuspec command line argument was specified. +570 * +571 * @return true if the disableNuspec command line argument was specified; +572 * otherwise false +573 */ +574 public boolean isNuspecDisabled() { +575 return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC); +576 } +577 +578 /** +579 * Returns true if the disableAssembly command line argument was specified. +580 * +581 * @return true if the disableAssembly command line argument was specified; +582 * otherwise false 583 */ -584 public boolean isPythonDistributionDisabled() { -585 return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST); +584 public boolean isAssemblyDisabled() { +585 return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY); 586 } 587 588 /** -589 * Returns true if the disablePyPkg command line argument was specified. -590 * -591 * @return true if the disablePyPkg command line argument was specified; otherwise false -592 */ -593 public boolean isPythonPackageDisabled() { -594 return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG); -595 } -596 -597 /** -598 * Returns whether the Ruby gemspec analyzer is disabled. -599 * -600 * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line argument was specified; otherwise false -601 */ -602 public boolean isRubyGemspecDisabled() { -603 return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS); -604 } -605 -606 /** -607 * Returns true if the disableCmake command line argument was specified. -608 * -609 * @return true if the disableCmake command line argument was specified; otherwise false -610 */ -611 public boolean isCmakeDisabled() { -612 return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE); -613 } -614 -615 /** -616 * Returns true if the disableAutoconf command line argument was specified. -617 * -618 * @return true if the disableAutoconf command line argument was specified; otherwise false -619 */ -620 public boolean isAutoconfDisabled() { -621 return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF); -622 } -623 -624 /** -625 * Returns true if the disableComposer command line argument was specified. -626 * -627 * @return true if the disableComposer command line argument was specified; otherwise false -628 */ -629 public boolean isComposerDisabled() { -630 return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER); -631 } -632 -633 /** -634 * Returns true if the disableNexus command line argument was specified. -635 * -636 * @return true if the disableNexus command line argument was specified; otherwise false -637 */ -638 public boolean isNexusDisabled() { -639 return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS); -640 } -641 -642 /** -643 * Returns true if the disableOpenSSL command line argument was specified. -644 * -645 * @return true if the disableOpenSSL command line argument was specified; otherwise false -646 */ -647 public boolean isOpenSSLDisabled() { -648 return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL); -649 } -650 -651 /** -652 * Returns true if the disableNodeJS command line argument was specified. -653 * -654 * @return true if the disableNodeJS command line argument was specified; otherwise false -655 */ -656 public boolean isNodeJsDisabled() { -657 return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS); -658 } -659 -660 /** -661 * Returns true if the disableCentral command line argument was specified. -662 * -663 * @return true if the disableCentral command line argument was specified; otherwise false +589 * Returns true if the disableBundleAudit command line argument was +590 * specified. +591 * +592 * @return true if the disableBundleAudit command line argument was +593 * specified; otherwise false +594 */ +595 public boolean isBundleAuditDisabled() { +596 return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT); +597 } +598 +599 /** +600 * Returns true if the disablePyDist command line argument was specified. +601 * +602 * @return true if the disablePyDist command line argument was specified; +603 * otherwise false +604 */ +605 public boolean isPythonDistributionDisabled() { +606 return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST); +607 } +608 +609 /** +610 * Returns true if the disablePyPkg command line argument was specified. +611 * +612 * @return true if the disablePyPkg command line argument was specified; +613 * otherwise false +614 */ +615 public boolean isPythonPackageDisabled() { +616 return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG); +617 } +618 +619 /** +620 * Returns whether the Ruby gemspec analyzer is disabled. +621 * +622 * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line +623 * argument was specified; otherwise false +624 */ +625 public boolean isRubyGemspecDisabled() { +626 return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS); +627 } +628 +629 /** +630 * Returns true if the disableCmake command line argument was specified. +631 * +632 * @return true if the disableCmake command line argument was specified; +633 * otherwise false +634 */ +635 public boolean isCmakeDisabled() { +636 return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE); +637 } +638 +639 /** +640 * Returns true if the disableAutoconf command line argument was specified. +641 * +642 * @return true if the disableAutoconf command line argument was specified; +643 * otherwise false +644 */ +645 public boolean isAutoconfDisabled() { +646 return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF); +647 } +648 +649 /** +650 * Returns true if the disableComposer command line argument was specified. +651 * +652 * @return true if the disableComposer command line argument was specified; +653 * otherwise false +654 */ +655 public boolean isComposerDisabled() { +656 return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER); +657 } +658 +659 /** +660 * Returns true if the disableNexus command line argument was specified. +661 * +662 * @return true if the disableNexus command line argument was specified; +663 * otherwise false 664 */ -665 public boolean isCentralDisabled() { -666 return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL); +665 public boolean isNexusDisabled() { +666 return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS); 667 } 668 669 /** -670 * Returns the url to the nexus server if one was specified. +670 * Returns true if the disableOpenSSL command line argument was specified. 671 * -672 * @return the url to the nexus server; if none was specified this will return null; -673 */ -674 public String getNexusUrl() { -675 if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) { -676 return null; -677 } else { -678 return line.getOptionValue(ARGUMENT.NEXUS_URL); -679 } -680 } -681 -682 /** -683 * Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is returned. -684 * -685 * @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false -686 */ -687 public boolean isNexusUsesProxy() { -688 // If they didn't specify whether Nexus needs to use the proxy, we should -689 // still honor the property if it's set. -690 if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) { -691 try { -692 return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY); -693 } catch (InvalidSettingException ise) { -694 return true; -695 } -696 } else { -697 return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY)); -698 } -699 } -700 -701 /** -702 * Displays the command line help message to the standard output. -703 */ -704 public void printHelp() { -705 final HelpFormatter formatter = new HelpFormatter(); -706 final Options options = new Options(); -707 addStandardOptions(options); -708 if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) { -709 addAdvancedOptions(options); +672 * @return true if the disableOpenSSL command line argument was specified; +673 * otherwise false +674 */ +675 public boolean isOpenSSLDisabled() { +676 return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL); +677 } +678 +679 /** +680 * Returns true if the disableNodeJS command line argument was specified. +681 * +682 * @return true if the disableNodeJS command line argument was specified; +683 * otherwise false +684 */ +685 public boolean isNodeJsDisabled() { +686 return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS); +687 } +688 +689 /** +690 * Returns true if the disableCentral command line argument was specified. +691 * +692 * @return true if the disableCentral command line argument was specified; +693 * otherwise false +694 */ +695 public boolean isCentralDisabled() { +696 return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL); +697 } +698 +699 /** +700 * Returns the url to the nexus server if one was specified. +701 * +702 * @return the url to the nexus server; if none was specified this will +703 * return null; +704 */ +705 public String getNexusUrl() { +706 if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) { +707 return null; +708 } else { +709 return line.getOptionValue(ARGUMENT.NEXUS_URL); 710 } -711 final String helpMsg = String.format("%n%s" -712 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. " -713 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n", -714 Settings.getString("application.name", "DependencyCheck"), -715 Settings.getString("application.name", "DependencyCheck")); -716 -717 formatter.printHelp(Settings.getString("application.name", "DependencyCheck"), -718 helpMsg, -719 options, -720 "", -721 true); -722 } -723 -724 /** -725 * Retrieves the file command line parameter(s) specified for the 'scan' argument. -726 * -727 * @return the file paths specified on the command line for scan -728 */ -729 public String[] getScanFiles() { -730 return line.getOptionValues(ARGUMENT.SCAN); -731 } -732 -733 /** -734 * Retrieves the list of excluded file patterns specified by the 'exclude' argument. -735 * -736 * @return the excluded file patterns -737 */ -738 public String[] getExcludeList() { -739 return line.getOptionValues(ARGUMENT.EXCLUDE); -740 } -741 -742 /** -743 * Returns the directory to write the reports to specified on the command line. -744 * -745 * @return the path to the reports directory. -746 */ -747 public String getReportDirectory() { -748 return line.getOptionValue(ARGUMENT.OUT, "."); -749 } -750 -751 /** -752 * Returns the path to Mono for .NET Assembly analysis on non-windows systems. -753 * -754 * @return the path to Mono -755 */ -756 public String getPathToMono() { -757 return line.getOptionValue(ARGUMENT.PATH_TO_MONO); -758 } -759 -760 /** -761 * Returns the path to bundle-audit for Ruby bundle analysis. -762 * -763 * @return the path to Mono -764 */ -765 public String getPathToBundleAudit() { -766 return line.getOptionValue(ARGUMENT.PATH_TO_BUNDLE_AUDIT); -767 } -768 -769 /** -770 * Returns the output format specified on the command line. Defaults to HTML if no format was specified. -771 * -772 * @return the output format name. -773 */ -774 public String getReportFormat() { -775 return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML"); -776 } -777 -778 /** -779 * Returns the application name specified on the command line. +711 } +712 +713 /** +714 * Returns true if the Nexus Analyzer should use the configured proxy to +715 * connect to Nexus; otherwise false is returned. +716 * +717 * @return true if the Nexus Analyzer should use the configured proxy to +718 * connect to Nexus; otherwise false +719 */ +720 public boolean isNexusUsesProxy() { +721 // If they didn't specify whether Nexus needs to use the proxy, we should +722 // still honor the property if it's set. +723 if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) { +724 try { +725 return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY); +726 } catch (InvalidSettingException ise) { +727 return true; +728 } +729 } else { +730 return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY)); +731 } +732 } +733 +734 /** +735 * Displays the command line help message to the standard output. +736 */ +737 public void printHelp() { +738 final HelpFormatter formatter = new HelpFormatter(); +739 final Options options = new Options(); +740 addStandardOptions(options); +741 if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) { +742 addAdvancedOptions(options); +743 } +744 final String helpMsg = String.format("%n%s" +745 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. " +746 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n", +747 Settings.getString("application.name", "DependencyCheck"), +748 Settings.getString("application.name", "DependencyCheck")); +749 +750 formatter.printHelp(Settings.getString("application.name", "DependencyCheck"), +751 helpMsg, +752 options, +753 "", +754 true); +755 } +756 +757 /** +758 * Retrieves the file command line parameter(s) specified for the 'scan' +759 * argument. +760 * +761 * @return the file paths specified on the command line for scan +762 */ +763 public String[] getScanFiles() { +764 return line.getOptionValues(ARGUMENT.SCAN); +765 } +766 +767 /** +768 * Retrieves the list of excluded file patterns specified by the 'exclude' +769 * argument. +770 * +771 * @return the excluded file patterns +772 */ +773 public String[] getExcludeList() { +774 return line.getOptionValues(ARGUMENT.EXCLUDE); +775 } +776 +777 /** +778 * Returns the directory to write the reports to specified on the command +779 * line. 780 * -781 * @return the application name. +781 * @return the path to the reports directory. 782 */ -783 public String getProjectName() { -784 final String appName = line.getOptionValue(ARGUMENT.APP_NAME); -785 String name = line.getOptionValue(ARGUMENT.PROJECT); -786 if (name == null && appName != null) { -787 name = appName; -788 LOGGER.warn("The '" + ARGUMENT.APP_NAME + "' argument should no longer be used; use '" + ARGUMENT.PROJECT + "' instead."); -789 } -790 return name; -791 } -792 -793 /** -794 * Returns the base URL for the CVE 1.2 XMl file. -795 * -796 * @return the URL to the CVE 1.2 XML file. -797 */ -798 public String getBaseCve12Url() { -799 return line.getOptionValue(ARGUMENT.CVE_BASE_12); -800 } -801 -802 /** -803 * Returns the base URL for the CVE 2.0 XMl file. -804 * -805 * @return the URL to the CVE 2.0 XML file. -806 */ -807 public String getBaseCve20Url() { -808 return line.getOptionValue(ARGUMENT.CVE_BASE_20); -809 } -810 -811 /** -812 * Returns the URL for the modified CVE 1.2 XMl file. -813 * -814 * @return the URL to the modified CVE 1.2 XML file. -815 */ -816 public String getModifiedCve12Url() { -817 return line.getOptionValue(ARGUMENT.CVE_MOD_12); -818 } -819 -820 /** -821 * Returns the URL for the modified CVE 2.0 XMl file. -822 * -823 * @return the URL to the modified CVE 2.0 XML file. -824 */ -825 public String getModifiedCve20Url() { -826 return line.getOptionValue(ARGUMENT.CVE_MOD_20); -827 } -828 -829 /** -830 * Returns the connection timeout. -831 * -832 * @return the connection timeout -833 */ -834 public String getConnectionTimeout() { -835 return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT); -836 } -837 -838 /** -839 * Returns the proxy server. -840 * -841 * @return the proxy server -842 */ -843 @SuppressWarnings("deprecation") -844 public String getProxyServer() { -845 -846 String server = line.getOptionValue(ARGUMENT.PROXY_SERVER); -847 if (server == null) { -848 server = line.getOptionValue(ARGUMENT.PROXY_URL); -849 if (server != null) { -850 LOGGER.warn("An old command line argument 'proxyurl' was detected; use proxyserver instead"); -851 } -852 } -853 return server; -854 } -855 -856 /** -857 * Returns the proxy port. -858 * -859 * @return the proxy port -860 */ -861 public String getProxyPort() { -862 return line.getOptionValue(ARGUMENT.PROXY_PORT); -863 } -864 -865 /** -866 * Returns the proxy username. -867 * -868 * @return the proxy username -869 */ -870 public String getProxyUsername() { -871 return line.getOptionValue(ARGUMENT.PROXY_USERNAME); -872 } -873 -874 /** -875 * Returns the proxy password. -876 * -877 * @return the proxy password -878 */ -879 public String getProxyPassword() { -880 return line.getOptionValue(ARGUMENT.PROXY_PASSWORD); -881 } -882 -883 /** -884 * Get the value of dataDirectory. -885 * -886 * @return the value of dataDirectory -887 */ -888 public String getDataDirectory() { -889 return line.getOptionValue(ARGUMENT.DATA_DIRECTORY); -890 } -891 -892 /** -893 * Returns the properties file specified on the command line. -894 * -895 * @return the properties file specified on the command line -896 */ -897 public File getPropertiesFile() { -898 final String path = line.getOptionValue(ARGUMENT.PROP); -899 if (path != null) { -900 return new File(path); -901 } -902 return null; -903 } -904 -905 /** -906 * Returns the path to the verbose log file. -907 * -908 * @return the path to the verbose log file -909 */ -910 public String getVerboseLog() { -911 return line.getOptionValue(ARGUMENT.VERBOSE_LOG); -912 } -913 -914 /** -915 * Returns the path to the suppression file. -916 * -917 * @return the path to the suppression file -918 */ -919 public String getSuppressionFile() { -920 return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE); -921 } -922 -923 /** -924 * <p> -925 * Prints the manifest information to standard output.</p> -926 * <ul><li>Implementation-Title: ${pom.name}</li> -927 * <li>Implementation-Version: ${pom.version}</li></ul> -928 */ -929 public void printVersionInfo() { -930 final String version = String.format("%s version %s", -931 Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"), -932 Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); -933 System.out.println(version); -934 } -935 -936 /** -937 * Checks if the auto update feature has been disabled. If it has been disabled via the command line this will return false. -938 * -939 * @return <code>true</code> if auto-update is allowed; otherwise <code>false</code> -940 */ -941 public boolean isAutoUpdate() { -942 return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE); -943 } -944 -945 /** -946 * Checks if the update only flag has been set. -947 * -948 * @return <code>true</code> if the update only flag has been set; otherwise <code>false</code>. -949 */ -950 public boolean isUpdateOnly() { -951 return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY); -952 } -953 -954 /** -955 * Checks if the purge NVD flag has been set. -956 * -957 * @return <code>true</code> if the purge nvd flag has been set; otherwise <code>false</code>. -958 */ -959 public boolean isPurge() { -960 return line != null && line.hasOption(ARGUMENT.PURGE_NVD); -961 } -962 -963 /** -964 * Returns the database driver name if specified; otherwise null is returned. -965 * -966 * @return the database driver name if specified; otherwise null is returned -967 */ -968 public String getDatabaseDriverName() { -969 return line.getOptionValue(ARGUMENT.DB_DRIVER); -970 } -971 -972 /** -973 * Returns the database driver path if specified; otherwise null is returned. -974 * -975 * @return the database driver name if specified; otherwise null is returned -976 */ -977 public String getDatabaseDriverPath() { -978 return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH); -979 } -980 -981 /** -982 * Returns the database connection string if specified; otherwise null is returned. -983 * -984 * @return the database connection string if specified; otherwise null is returned -985 */ -986 public String getConnectionString() { -987 return line.getOptionValue(ARGUMENT.CONNECTION_STRING); -988 } -989 -990 /** -991 * Returns the database database user name if specified; otherwise null is returned. -992 * -993 * @return the database database user name if specified; otherwise null is returned -994 */ -995 public String getDatabaseUser() { -996 return line.getOptionValue(ARGUMENT.DB_NAME); -997 } -998 -999 /** -1000 * Returns the database database password if specified; otherwise null is returned. -1001 * -1002 * @return the database database password if specified; otherwise null is returned -1003 */ -1004 public String getDatabasePassword() { -1005 return line.getOptionValue(ARGUMENT.DB_PASSWORD); -1006 } -1007 -1008 /** -1009 * Returns the additional Extensions if specified; otherwise null is returned. -1010 * -1011 * @return the additional Extensions; otherwise null is returned -1012 */ -1013 public String getAdditionalZipExtensions() { -1014 return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS); -1015 } -1016 -1017 /** -1018 * Get the value of cveValidForHours. -1019 * -1020 * @return the value of cveValidForHours -1021 */ -1022 public Integer getCveValidForHours() { -1023 final String v = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS); -1024 if (v != null) { -1025 return Integer.parseInt(v); -1026 } -1027 return null; -1028 } -1029 -1030 /** -1031 * A collection of static final strings that represent the possible command line arguments. -1032 */ -1033 public static class ARGUMENT { -1034 -1035 /** -1036 * The long CLI argument name specifying the directory/file to scan. -1037 */ -1038 public static final String SCAN = "scan"; -1039 /** -1040 * The short CLI argument name specifying the directory/file to scan. -1041 */ -1042 public static final String SCAN_SHORT = "s"; -1043 /** -1044 * The long CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. -1045 */ -1046 public static final String DISABLE_AUTO_UPDATE = "noupdate"; -1047 /** -1048 * The short CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. -1049 */ -1050 public static final String DISABLE_AUTO_UPDATE_SHORT = "n"; -1051 /** -1052 * The long CLI argument name specifying that only the update phase should be executed; no scan should be run. -1053 */ -1054 public static final String UPDATE_ONLY = "updateonly"; -1055 /** -1056 * The long CLI argument name specifying that only the update phase should be executed; no scan should be run. -1057 */ -1058 public static final String PURGE_NVD = "purge"; -1059 /** -1060 * The long CLI argument name specifying the directory to write the reports to. -1061 */ -1062 public static final String OUT = "out"; -1063 /** -1064 * The short CLI argument name specifying the directory to write the reports to. -1065 */ -1066 public static final String OUT_SHORT = "o"; -1067 /** -1068 * The long CLI argument name specifying the output format to write the reports to. -1069 */ -1070 public static final String OUTPUT_FORMAT = "format"; -1071 /** -1072 * The short CLI argument name specifying the output format to write the reports to. -1073 */ -1074 public static final String OUTPUT_FORMAT_SHORT = "f"; -1075 /** -1076 * The long CLI argument name specifying the name of the project to be scanned. -1077 */ -1078 public static final String PROJECT = "project"; -1079 /** -1080 * The long CLI argument name specifying the name of the application to be scanned. -1081 * -1082 * @deprecated project should be used instead -1083 */ -1084 @Deprecated -1085 public static final String APP_NAME = "app"; -1086 /** -1087 * The short CLI argument name specifying the name of the application to be scanned. -1088 * -1089 * @deprecated project should be used instead -1090 */ -1091 @Deprecated -1092 public static final String APP_NAME_SHORT = "a"; -1093 /** -1094 * The long CLI argument name asking for help. -1095 */ -1096 public static final String HELP = "help"; -1097 /** -1098 * The long CLI argument name asking for advanced help. -1099 */ -1100 public static final String ADVANCED_HELP = "advancedHelp"; -1101 /** -1102 * The short CLI argument name asking for help. -1103 */ -1104 public static final String HELP_SHORT = "h"; -1105 /** -1106 * The long CLI argument name asking for the version. +783 public String getReportDirectory() { +784 return line.getOptionValue(ARGUMENT.OUT, "."); +785 } +786 +787 /** +788 * Returns the path to Mono for .NET Assembly analysis on non-windows +789 * systems. +790 * +791 * @return the path to Mono +792 */ +793 public String getPathToMono() { +794 return line.getOptionValue(ARGUMENT.PATH_TO_MONO); +795 } +796 +797 /** +798 * Returns the path to bundle-audit for Ruby bundle analysis. +799 * +800 * @return the path to Mono +801 */ +802 public String getPathToBundleAudit() { +803 return line.getOptionValue(ARGUMENT.PATH_TO_BUNDLE_AUDIT); +804 } +805 +806 /** +807 * Returns the output format specified on the command line. Defaults to HTML +808 * if no format was specified. +809 * +810 * @return the output format name. +811 */ +812 public String getReportFormat() { +813 return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML"); +814 } +815 +816 /** +817 * Returns the application name specified on the command line. +818 * +819 * @return the application name. +820 */ +821 public String getProjectName() { +822 final String appName = line.getOptionValue(ARGUMENT.APP_NAME); +823 String name = line.getOptionValue(ARGUMENT.PROJECT); +824 if (name == null && appName != null) { +825 name = appName; +826 LOGGER.warn("The '" + ARGUMENT.APP_NAME + "' argument should no longer be used; use '" + ARGUMENT.PROJECT + "' instead."); +827 } +828 return name; +829 } +830 +831 /** +832 * Returns the base URL for the CVE 1.2 XMl file. +833 * +834 * @return the URL to the CVE 1.2 XML file. +835 */ +836 public String getBaseCve12Url() { +837 return line.getOptionValue(ARGUMENT.CVE_BASE_12); +838 } +839 +840 /** +841 * Returns the base URL for the CVE 2.0 XMl file. +842 * +843 * @return the URL to the CVE 2.0 XML file. +844 */ +845 public String getBaseCve20Url() { +846 return line.getOptionValue(ARGUMENT.CVE_BASE_20); +847 } +848 +849 /** +850 * Returns the URL for the modified CVE 1.2 XMl file. +851 * +852 * @return the URL to the modified CVE 1.2 XML file. +853 */ +854 public String getModifiedCve12Url() { +855 return line.getOptionValue(ARGUMENT.CVE_MOD_12); +856 } +857 +858 /** +859 * Returns the URL for the modified CVE 2.0 XMl file. +860 * +861 * @return the URL to the modified CVE 2.0 XML file. +862 */ +863 public String getModifiedCve20Url() { +864 return line.getOptionValue(ARGUMENT.CVE_MOD_20); +865 } +866 +867 /** +868 * Returns the connection timeout. +869 * +870 * @return the connection timeout +871 */ +872 public String getConnectionTimeout() { +873 return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT); +874 } +875 +876 /** +877 * Returns the proxy server. +878 * +879 * @return the proxy server +880 */ +881 @SuppressWarnings("deprecation") +882 public String getProxyServer() { +883 +884 String server = line.getOptionValue(ARGUMENT.PROXY_SERVER); +885 if (server == null) { +886 server = line.getOptionValue(ARGUMENT.PROXY_URL); +887 if (server != null) { +888 LOGGER.warn("An old command line argument 'proxyurl' was detected; use proxyserver instead"); +889 } +890 } +891 return server; +892 } +893 +894 /** +895 * Returns the proxy port. +896 * +897 * @return the proxy port +898 */ +899 public String getProxyPort() { +900 return line.getOptionValue(ARGUMENT.PROXY_PORT); +901 } +902 +903 /** +904 * Returns the proxy username. +905 * +906 * @return the proxy username +907 */ +908 public String getProxyUsername() { +909 return line.getOptionValue(ARGUMENT.PROXY_USERNAME); +910 } +911 +912 /** +913 * Returns the proxy password. +914 * +915 * @return the proxy password +916 */ +917 public String getProxyPassword() { +918 return line.getOptionValue(ARGUMENT.PROXY_PASSWORD); +919 } +920 +921 /** +922 * Get the value of dataDirectory. +923 * +924 * @return the value of dataDirectory +925 */ +926 public String getDataDirectory() { +927 return line.getOptionValue(ARGUMENT.DATA_DIRECTORY); +928 } +929 +930 /** +931 * Returns the properties file specified on the command line. +932 * +933 * @return the properties file specified on the command line +934 */ +935 public File getPropertiesFile() { +936 final String path = line.getOptionValue(ARGUMENT.PROP); +937 if (path != null) { +938 return new File(path); +939 } +940 return null; +941 } +942 +943 /** +944 * Returns the path to the verbose log file. +945 * +946 * @return the path to the verbose log file +947 */ +948 public String getVerboseLog() { +949 return line.getOptionValue(ARGUMENT.VERBOSE_LOG); +950 } +951 +952 /** +953 * Returns the path to the suppression file. +954 * +955 * @return the path to the suppression file +956 */ +957 public String getSuppressionFile() { +958 return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE); +959 } +960 +961 /** +962 * <p> +963 * Prints the manifest information to standard output.</p> +964 * <ul><li>Implementation-Title: ${pom.name}</li> +965 * <li>Implementation-Version: ${pom.version}</li></ul> +966 */ +967 public void printVersionInfo() { +968 final String version = String.format("%s version %s", +969 Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"), +970 Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); +971 System.out.println(version); +972 } +973 +974 /** +975 * Checks if the auto update feature has been disabled. If it has been +976 * disabled via the command line this will return false. +977 * +978 * @return <code>true</code> if auto-update is allowed; otherwise +979 * <code>false</code> +980 */ +981 public boolean isAutoUpdate() { +982 return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE); +983 } +984 +985 /** +986 * Checks if the update only flag has been set. +987 * +988 * @return <code>true</code> if the update only flag has been set; otherwise +989 * <code>false</code>. +990 */ +991 public boolean isUpdateOnly() { +992 return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY); +993 } +994 +995 /** +996 * Checks if the purge NVD flag has been set. +997 * +998 * @return <code>true</code> if the purge nvd flag has been set; otherwise +999 * <code>false</code>. +1000 */ +1001 public boolean isPurge() { +1002 return line != null && line.hasOption(ARGUMENT.PURGE_NVD); +1003 } +1004 +1005 /** +1006 * Returns the database driver name if specified; otherwise null is +1007 * returned. +1008 * +1009 * @return the database driver name if specified; otherwise null is returned +1010 */ +1011 public String getDatabaseDriverName() { +1012 return line.getOptionValue(ARGUMENT.DB_DRIVER); +1013 } +1014 +1015 /** +1016 * Returns the database driver path if specified; otherwise null is +1017 * returned. +1018 * +1019 * @return the database driver name if specified; otherwise null is returned +1020 */ +1021 public String getDatabaseDriverPath() { +1022 return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH); +1023 } +1024 +1025 /** +1026 * Returns the database connection string if specified; otherwise null is +1027 * returned. +1028 * +1029 * @return the database connection string if specified; otherwise null is +1030 * returned +1031 */ +1032 public String getConnectionString() { +1033 return line.getOptionValue(ARGUMENT.CONNECTION_STRING); +1034 } +1035 +1036 /** +1037 * Returns the database database user name if specified; otherwise null is +1038 * returned. +1039 * +1040 * @return the database database user name if specified; otherwise null is +1041 * returned +1042 */ +1043 public String getDatabaseUser() { +1044 return line.getOptionValue(ARGUMENT.DB_NAME); +1045 } +1046 +1047 /** +1048 * Returns the database database password if specified; otherwise null is +1049 * returned. +1050 * +1051 * @return the database database password if specified; otherwise null is +1052 * returned +1053 */ +1054 public String getDatabasePassword() { +1055 return line.getOptionValue(ARGUMENT.DB_PASSWORD); +1056 } +1057 +1058 /** +1059 * Returns the additional Extensions if specified; otherwise null is +1060 * returned. +1061 * +1062 * @return the additional Extensions; otherwise null is returned +1063 */ +1064 public String getAdditionalZipExtensions() { +1065 return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS); +1066 } +1067 +1068 /** +1069 * Get the value of cveValidForHours. +1070 * +1071 * @return the value of cveValidForHours +1072 */ +1073 public Integer getCveValidForHours() { +1074 final String v = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS); +1075 if (v != null) { +1076 return Integer.parseInt(v); +1077 } +1078 return null; +1079 } +1080 +1081 /** +1082 * Returns true if the experimental analyzers are enabled. +1083 * +1084 * @return true if the experimental analyzers are enabled; otherwise false +1085 */ +1086 public boolean isExperimentalEnabled() { +1087 return line.hasOption(ARGUMENT.EXPERIMENTAL); +1088 } +1089 +1090 /** +1091 * A collection of static final strings that represent the possible command +1092 * line arguments. +1093 */ +1094 public static class ARGUMENT { +1095 +1096 /** +1097 * The long CLI argument name specifying the directory/file to scan. +1098 */ +1099 public static final String SCAN = "scan"; +1100 /** +1101 * The short CLI argument name specifying the directory/file to scan. +1102 */ +1103 public static final String SCAN_SHORT = "s"; +1104 /** +1105 * The long CLI argument name specifying that the CPE/CVE/etc. data +1106 * should not be automatically updated. 1107 */ -1108 public static final String VERSION_SHORT = "v"; +1108 public static final String DISABLE_AUTO_UPDATE = "noupdate"; 1109 /** -1110 * The short CLI argument name asking for the version. -1111 */ -1112 public static final String VERSION = "version"; -1113 /** -1114 * The CLI argument name indicating the proxy port. -1115 */ -1116 public static final String PROXY_PORT = "proxyport"; -1117 /** -1118 * The CLI argument name indicating the proxy server. -1119 */ -1120 public static final String PROXY_SERVER = "proxyserver"; -1121 /** -1122 * The CLI argument name indicating the proxy url. -1123 * -1124 * @deprecated use {@link #PROXY_SERVER} instead -1125 */ -1126 @Deprecated -1127 public static final String PROXY_URL = "proxyurl"; -1128 /** -1129 * The CLI argument name indicating the proxy username. -1130 */ -1131 public static final String PROXY_USERNAME = "proxyuser"; -1132 /** -1133 * The CLI argument name indicating the proxy password. -1134 */ -1135 public static final String PROXY_PASSWORD = "proxypass"; -1136 /** -1137 * The short CLI argument name indicating the connection timeout. -1138 */ -1139 public static final String CONNECTION_TIMEOUT_SHORT = "c"; -1140 /** -1141 * The CLI argument name indicating the connection timeout. +1110 * The short CLI argument name specifying that the CPE/CVE/etc. data +1111 * should not be automatically updated. +1112 */ +1113 public static final String DISABLE_AUTO_UPDATE_SHORT = "n"; +1114 /** +1115 * The long CLI argument name specifying that only the update phase +1116 * should be executed; no scan should be run. +1117 */ +1118 public static final String UPDATE_ONLY = "updateonly"; +1119 /** +1120 * The long CLI argument name specifying that only the update phase +1121 * should be executed; no scan should be run. +1122 */ +1123 public static final String PURGE_NVD = "purge"; +1124 /** +1125 * The long CLI argument name specifying the directory to write the +1126 * reports to. +1127 */ +1128 public static final String OUT = "out"; +1129 /** +1130 * The short CLI argument name specifying the directory to write the +1131 * reports to. +1132 */ +1133 public static final String OUT_SHORT = "o"; +1134 /** +1135 * The long CLI argument name specifying the output format to write the +1136 * reports to. +1137 */ +1138 public static final String OUTPUT_FORMAT = "format"; +1139 /** +1140 * The short CLI argument name specifying the output format to write the +1141 * reports to. 1142 */ -1143 public static final String CONNECTION_TIMEOUT = "connectiontimeout"; +1143 public static final String OUTPUT_FORMAT_SHORT = "f"; 1144 /** -1145 * The short CLI argument name for setting the location of an additional properties file. -1146 */ -1147 public static final String PROP_SHORT = "P"; -1148 /** -1149 * The CLI argument name for setting the location of an additional properties file. -1150 */ -1151 public static final String PROP = "propertyfile"; -1152 /** -1153 * The CLI argument name for setting the location of the data directory. +1145 * The long CLI argument name specifying the name of the project to be +1146 * scanned. +1147 */ +1148 public static final String PROJECT = "project"; +1149 /** +1150 * The long CLI argument name specifying the name of the application to +1151 * be scanned. +1152 * +1153 * @deprecated project should be used instead 1154 */ -1155 public static final String DATA_DIRECTORY = "data"; -1156 /** -1157 * The CLI argument name for setting the URL for the CVE Data Files. -1158 */ -1159 public static final String CVE_MOD_12 = "cveUrl12Modified"; -1160 /** -1161 * The CLI argument name for setting the URL for the CVE Data Files. +1155 @Deprecated +1156 public static final String APP_NAME = "app"; +1157 /** +1158 * The short CLI argument name specifying the name of the application to +1159 * be scanned. +1160 * +1161 * @deprecated project should be used instead 1162 */ -1163 public static final String CVE_MOD_20 = "cveUrl20Modified"; -1164 /** -1165 * The CLI argument name for setting the URL for the CVE Data Files. -1166 */ -1167 public static final String CVE_BASE_12 = "cveUrl12Base"; -1168 /** -1169 * The CLI argument name for setting the URL for the CVE Data Files. -1170 */ -1171 public static final String CVE_BASE_20 = "cveUrl20Base"; -1172 /** -1173 * The short CLI argument name for setting the location of the data directory. -1174 */ -1175 public static final String DATA_DIRECTORY_SHORT = "d"; -1176 /** -1177 * The CLI argument name for setting the location of the data directory. -1178 */ -1179 public static final String VERBOSE_LOG = "log"; -1180 /** -1181 * The short CLI argument name for setting the location of the data directory. -1182 */ -1183 public static final String VERBOSE_LOG_SHORT = "l"; -1184 +1163 @Deprecated +1164 public static final String APP_NAME_SHORT = "a"; +1165 /** +1166 * The long CLI argument name asking for help. +1167 */ +1168 public static final String HELP = "help"; +1169 /** +1170 * The long CLI argument name asking for advanced help. +1171 */ +1172 public static final String ADVANCED_HELP = "advancedHelp"; +1173 /** +1174 * The short CLI argument name asking for help. +1175 */ +1176 public static final String HELP_SHORT = "h"; +1177 /** +1178 * The long CLI argument name asking for the version. +1179 */ +1180 public static final String VERSION_SHORT = "v"; +1181 /** +1182 * The short CLI argument name asking for the version. +1183 */ +1184 public static final String VERSION = "version"; 1185 /** -1186 * The CLI argument name for setting the depth of symbolic links that will be followed. +1186 * The CLI argument name indicating the proxy port. 1187 */ -1188 public static final String SYM_LINK_DEPTH = "symLink"; +1188 public static final String PROXY_PORT = "proxyport"; 1189 /** -1190 * The CLI argument name for setting the location of the suppression file. +1190 * The CLI argument name indicating the proxy server. 1191 */ -1192 public static final String SUPPRESSION_FILE = "suppression"; +1192 public static final String PROXY_SERVER = "proxyserver"; 1193 /** -1194 * The CLI argument name for setting the location of the suppression file. -1195 */ -1196 public static final String CVE_VALID_FOR_HOURS = "cveValidForHours"; -1197 /** -1198 * Disables the Jar Analyzer. -1199 */ -1200 public static final String DISABLE_JAR = "disableJar"; -1201 /** -1202 * Disables the Archive Analyzer. -1203 */ -1204 public static final String DISABLE_ARCHIVE = "disableArchive"; -1205 /** -1206 * Disables the Python Distribution Analyzer. -1207 */ -1208 public static final String DISABLE_PY_DIST = "disablePyDist"; -1209 /** -1210 * Disables the Python Package Analyzer. -1211 */ -1212 public static final String DISABLE_PY_PKG = "disablePyPkg"; -1213 /** -1214 * Disables the Python Package Analyzer. -1215 */ -1216 public static final String DISABLE_COMPOSER = "disableComposer"; -1217 /** -1218 * Disables the Ruby Gemspec Analyzer. +1194 * The CLI argument name indicating the proxy url. +1195 * +1196 * @deprecated use {@link #PROXY_SERVER} instead +1197 */ +1198 @Deprecated +1199 public static final String PROXY_URL = "proxyurl"; +1200 /** +1201 * The CLI argument name indicating the proxy username. +1202 */ +1203 public static final String PROXY_USERNAME = "proxyuser"; +1204 /** +1205 * The CLI argument name indicating the proxy password. +1206 */ +1207 public static final String PROXY_PASSWORD = "proxypass"; +1208 /** +1209 * The short CLI argument name indicating the connection timeout. +1210 */ +1211 public static final String CONNECTION_TIMEOUT_SHORT = "c"; +1212 /** +1213 * The CLI argument name indicating the connection timeout. +1214 */ +1215 public static final String CONNECTION_TIMEOUT = "connectiontimeout"; +1216 /** +1217 * The short CLI argument name for setting the location of an additional +1218 * properties file. 1219 */ -1220 public static final String DISABLE_RUBYGEMS = "disableRubygems"; +1220 public static final String PROP_SHORT = "P"; 1221 /** -1222 * Disables the Autoconf Analyzer. -1223 */ -1224 public static final String DISABLE_AUTOCONF = "disableAutoconf"; -1225 /** -1226 * Disables the Cmake Analyzer. -1227 */ -1228 public static final String DISABLE_CMAKE = "disableCmake"; -1229 /** -1230 * Disables the Assembly Analyzer. -1231 */ -1232 public static final String DISABLE_ASSEMBLY = "disableAssembly"; -1233 /** -1234 * Disables the Ruby Bundler Audit Analyzer. -1235 */ -1236 public static final String DISABLE_BUNDLE_AUDIT = "disableBundleAudit"; -1237 /** -1238 * Disables the Nuspec Analyzer. -1239 */ -1240 public static final String DISABLE_NUSPEC = "disableNuspec"; -1241 /** -1242 * Disables the Central Analyzer. -1243 */ -1244 public static final String DISABLE_CENTRAL = "disableCentral"; -1245 /** -1246 * Disables the Nexus Analyzer. -1247 */ -1248 public static final String DISABLE_NEXUS = "disableNexus"; -1249 /** -1250 * Disables the OpenSSL Analyzer. -1251 */ -1252 public static final String DISABLE_OPENSSL = "disableOpenSSL"; -1253 /** -1254 * Disables the Node.js Package Analyzer. -1255 */ -1256 public static final String DISABLE_NODE_JS = "disableNodeJS"; -1257 /** -1258 * The URL of the nexus server. -1259 */ -1260 public static final String NEXUS_URL = "nexus"; +1222 * The CLI argument name for setting the location of an additional +1223 * properties file. +1224 */ +1225 public static final String PROP = "propertyfile"; +1226 /** +1227 * The CLI argument name for setting the location of the data directory. +1228 */ +1229 public static final String DATA_DIRECTORY = "data"; +1230 /** +1231 * The CLI argument name for setting the URL for the CVE Data Files. +1232 */ +1233 public static final String CVE_MOD_12 = "cveUrl12Modified"; +1234 /** +1235 * The CLI argument name for setting the URL for the CVE Data Files. +1236 */ +1237 public static final String CVE_MOD_20 = "cveUrl20Modified"; +1238 /** +1239 * The CLI argument name for setting the URL for the CVE Data Files. +1240 */ +1241 public static final String CVE_BASE_12 = "cveUrl12Base"; +1242 /** +1243 * The CLI argument name for setting the URL for the CVE Data Files. +1244 */ +1245 public static final String CVE_BASE_20 = "cveUrl20Base"; +1246 /** +1247 * The short CLI argument name for setting the location of the data +1248 * directory. +1249 */ +1250 public static final String DATA_DIRECTORY_SHORT = "d"; +1251 /** +1252 * The CLI argument name for setting the location of the data directory. +1253 */ +1254 public static final String VERBOSE_LOG = "log"; +1255 /** +1256 * The short CLI argument name for setting the location of the data +1257 * directory. +1258 */ +1259 public static final String VERBOSE_LOG_SHORT = "l"; +1260 1261 /** -1262 * Whether or not the defined proxy should be used when connecting to Nexus. -1263 */ -1264 public static final String NEXUS_USES_PROXY = "nexusUsesProxy"; -1265 /** -1266 * The CLI argument name for setting the connection string. -1267 */ -1268 public static final String CONNECTION_STRING = "connectionString"; -1269 /** -1270 * The CLI argument name for setting the database user name. -1271 */ -1272 public static final String DB_NAME = "dbUser"; -1273 /** -1274 * The CLI argument name for setting the database password. -1275 */ -1276 public static final String DB_PASSWORD = "dbPassword"; -1277 /** -1278 * The CLI argument name for setting the database driver name. -1279 */ -1280 public static final String DB_DRIVER = "dbDriverName"; -1281 /** -1282 * The CLI argument name for setting the path to the database driver; in case it is not on the class path. -1283 */ -1284 public static final String DB_DRIVER_PATH = "dbDriverPath"; -1285 /** -1286 * The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems. -1287 */ -1288 public static final String PATH_TO_MONO = "mono"; -1289 /** -1290 * The CLI argument name for setting extra extensions. -1291 */ -1292 public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions"; -1293 /** -1294 * Exclude path argument. -1295 */ -1296 public static final String EXCLUDE = "exclude"; -1297 /** -1298 * The CLI argument name for setting the path to bundle-audit for Ruby bundle analysis. -1299 */ -1300 public static final String PATH_TO_BUNDLE_AUDIT = "bundleAudit"; -1301 } -1302 } +1262 * The CLI argument name for setting the depth of symbolic links that +1263 * will be followed. +1264 */ +1265 public static final String SYM_LINK_DEPTH = "symLink"; +1266 /** +1267 * The CLI argument name for setting the location of the suppression +1268 * file. +1269 */ +1270 public static final String SUPPRESSION_FILE = "suppression"; +1271 /** +1272 * The CLI argument name for setting the location of the suppression +1273 * file. +1274 */ +1275 public static final String CVE_VALID_FOR_HOURS = "cveValidForHours"; +1276 /** +1277 * Disables the Jar Analyzer. +1278 */ +1279 public static final String DISABLE_JAR = "disableJar"; +1280 /** +1281 * Disables the Archive Analyzer. +1282 */ +1283 public static final String DISABLE_ARCHIVE = "disableArchive"; +1284 /** +1285 * Disables the Python Distribution Analyzer. +1286 */ +1287 public static final String DISABLE_PY_DIST = "disablePyDist"; +1288 /** +1289 * Disables the Python Package Analyzer. +1290 */ +1291 public static final String DISABLE_PY_PKG = "disablePyPkg"; +1292 /** +1293 * Disables the Python Package Analyzer. +1294 */ +1295 public static final String DISABLE_COMPOSER = "disableComposer"; +1296 /** +1297 * Disables the Ruby Gemspec Analyzer. +1298 */ +1299 public static final String DISABLE_RUBYGEMS = "disableRubygems"; +1300 /** +1301 * Disables the Autoconf Analyzer. +1302 */ +1303 public static final String DISABLE_AUTOCONF = "disableAutoconf"; +1304 /** +1305 * Disables the Cmake Analyzer. +1306 */ +1307 public static final String DISABLE_CMAKE = "disableCmake"; +1308 /** +1309 * Disables the Assembly Analyzer. +1310 */ +1311 public static final String DISABLE_ASSEMBLY = "disableAssembly"; +1312 /** +1313 * Disables the Ruby Bundler Audit Analyzer. +1314 */ +1315 public static final String DISABLE_BUNDLE_AUDIT = "disableBundleAudit"; +1316 /** +1317 * Disables the Nuspec Analyzer. +1318 */ +1319 public static final String DISABLE_NUSPEC = "disableNuspec"; +1320 /** +1321 * Disables the Central Analyzer. +1322 */ +1323 public static final String DISABLE_CENTRAL = "disableCentral"; +1324 /** +1325 * Disables the Nexus Analyzer. +1326 */ +1327 public static final String DISABLE_NEXUS = "disableNexus"; +1328 /** +1329 * Disables the OpenSSL Analyzer. +1330 */ +1331 public static final String DISABLE_OPENSSL = "disableOpenSSL"; +1332 /** +1333 * Disables the Node.js Package Analyzer. +1334 */ +1335 public static final String DISABLE_NODE_JS = "disableNodeJS"; +1336 /** +1337 * The URL of the nexus server. +1338 */ +1339 public static final String NEXUS_URL = "nexus"; +1340 /** +1341 * Whether or not the defined proxy should be used when connecting to +1342 * Nexus. +1343 */ +1344 public static final String NEXUS_USES_PROXY = "nexusUsesProxy"; +1345 /** +1346 * The CLI argument name for setting the connection string. +1347 */ +1348 public static final String CONNECTION_STRING = "connectionString"; +1349 /** +1350 * The CLI argument name for setting the database user name. +1351 */ +1352 public static final String DB_NAME = "dbUser"; +1353 /** +1354 * The CLI argument name for setting the database password. +1355 */ +1356 public static final String DB_PASSWORD = "dbPassword"; +1357 /** +1358 * The CLI argument name for setting the database driver name. +1359 */ +1360 public static final String DB_DRIVER = "dbDriverName"; +1361 /** +1362 * The CLI argument name for setting the path to the database driver; in +1363 * case it is not on the class path. +1364 */ +1365 public static final String DB_DRIVER_PATH = "dbDriverPath"; +1366 /** +1367 * The CLI argument name for setting the path to mono for .NET Assembly +1368 * analysis on non-windows systems. +1369 */ +1370 public static final String PATH_TO_MONO = "mono"; +1371 /** +1372 * The CLI argument name for setting extra extensions. +1373 */ +1374 public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions"; +1375 /** +1376 * Exclude path argument. +1377 */ +1378 public static final String EXCLUDE = "exclude"; +1379 /** +1380 * The CLI argument name for setting the path to bundle-audit for Ruby +1381 * bundle analysis. +1382 */ +1383 public static final String PATH_TO_BUNDLE_AUDIT = "bundleAudit"; +1384 /** +1385 * The CLI argument to enable the experimental analyzers. +1386 */ +1387 private static final String EXPERIMENTAL = "enableExperimental"; +1388 } +1389 }
      diff --git a/xref/org/owasp/dependencycheck/Engine.html b/xref/org/owasp/dependencycheck/Engine.html index e0d2c869a..e8916237e 100644 --- a/xref/org/owasp/dependencycheck/Engine.html +++ b/xref/org/owasp/dependencycheck/Engine.html @@ -134,383 +134,382 @@ 126 } 127 128 final AnalyzerService service = new AnalyzerService(serviceClassLoader); -129 final Iterator<Analyzer> iterator = service.getAnalyzers(); -130 while (iterator.hasNext()) { -131 final Analyzer a = iterator.next(); -132 analyzers.get(a.getAnalysisPhase()).add(a); -133 if (a instanceof FileTypeAnalyzer) { -134 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); -135 } -136 } -137 } -138 -139 /** -140 * Get the List of the analyzers for a specific phase of analysis. -141 * -142 * @param phase the phase to get the configured analyzers. -143 * @return the analyzers loaded -144 */ -145 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { -146 return analyzers.get(phase); -147 } -148 -149 /** -150 * Get the dependencies identified. -151 * -152 * @return the dependencies identified -153 */ -154 public List<Dependency> getDependencies() { -155 return dependencies; -156 } -157 -158 /** -159 * Sets the dependencies. -160 * -161 * @param dependencies the dependencies -162 */ -163 public void setDependencies(List<Dependency> dependencies) { -164 this.dependencies = dependencies; -165 } -166 -167 /** -168 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -169 * identified are added to the dependency collection. -170 * -171 * @param paths an array of paths to files or directories to be analyzed -172 * @return the list of dependencies scanned -173 * @since v0.3.2.5 -174 */ -175 public List<Dependency> scan(String[] paths) { -176 final List<Dependency> deps = new ArrayList<Dependency>(); -177 for (String path : paths) { -178 final List<Dependency> d = scan(path); -179 if (d != null) { -180 deps.addAll(d); -181 } -182 } -183 return deps; -184 } -185 -186 /** -187 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified -188 * are added to the dependency collection. -189 * -190 * @param path the path to a file or directory to be analyzed -191 * @return the list of dependencies scanned -192 */ -193 public List<Dependency> scan(String path) { -194 final File file = new File(path); -195 return scan(file); -196 } -197 -198 /** -199 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -200 * identified are added to the dependency collection. -201 * -202 * @param files an array of paths to files or directories to be analyzed. -203 * @return the list of dependencies -204 * @since v0.3.2.5 -205 */ -206 public List<Dependency> scan(File[] files) { -207 final List<Dependency> deps = new ArrayList<Dependency>(); -208 for (File file : files) { -209 final List<Dependency> d = scan(file); -210 if (d != null) { -211 deps.addAll(d); -212 } -213 } -214 return deps; -215 } -216 -217 /** -218 * Scans a collection of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -219 * identified are added to the dependency collection. -220 * -221 * @param files a set of paths to files or directories to be analyzed -222 * @return the list of dependencies scanned -223 * @since v0.3.2.5 -224 */ -225 public List<Dependency> scan(Collection<File> files) { -226 final List<Dependency> deps = new ArrayList<Dependency>(); -227 for (File file : files) { -228 final List<Dependency> d = scan(file); -229 if (d != null) { -230 deps.addAll(d); -231 } -232 } -233 return deps; -234 } -235 -236 /** -237 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified -238 * are added to the dependency collection. -239 * -240 * @param file the path to a file or directory to be analyzed -241 * @return the list of dependencies scanned -242 * @since v0.3.2.4 -243 */ -244 public List<Dependency> scan(File file) { -245 if (file.exists()) { -246 if (file.isDirectory()) { -247 return scanDirectory(file); -248 } else { -249 final Dependency d = scanFile(file); -250 if (d != null) { -251 final List<Dependency> deps = new ArrayList<Dependency>(); -252 deps.add(d); -253 return deps; -254 } -255 } -256 } -257 return null; -258 } -259 -260 /** -261 * Recursively scans files and directories. Any dependencies identified are added to the dependency collection. -262 * -263 * @param dir the directory to scan -264 * @return the list of Dependency objects scanned -265 */ -266 protected List<Dependency> scanDirectory(File dir) { -267 final File[] files = dir.listFiles(); -268 final List<Dependency> deps = new ArrayList<Dependency>(); -269 if (files != null) { -270 for (File f : files) { -271 if (f.isDirectory()) { -272 final List<Dependency> d = scanDirectory(f); -273 if (d != null) { -274 deps.addAll(d); -275 } -276 } else { -277 final Dependency d = scanFile(f); -278 deps.add(d); -279 } -280 } -281 } -282 return deps; -283 } -284 -285 /** -286 * Scans a specified file. If a dependency is identified it is added to the dependency collection. -287 * -288 * @param file The file to scan -289 * @return the scanned dependency -290 */ -291 protected Dependency scanFile(File file) { -292 Dependency dependency = null; -293 if (file.isFile()) { -294 if (accept(file)) { -295 dependency = new Dependency(file); -296 dependencies.add(dependency); -297 } -298 } else { -299 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file); -300 } -301 return dependency; -302 } -303 -304 /** -305 * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via -306 * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for -307 * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the -308 * dependencies list. -309 */ -310 public void analyzeDependencies() { -311 boolean autoUpdate = true; -312 try { -313 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -314 } catch (InvalidSettingException ex) { -315 LOGGER.debug("Invalid setting for auto-update; using true."); -316 } -317 if (autoUpdate) { -318 doUpdates(); -319 } -320 -321 //need to ensure that data exists -322 try { -323 ensureDataExists(); -324 } catch (NoDataException ex) { -325 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); -326 LOGGER.debug("", ex); -327 return; -328 } catch (DatabaseException ex) { -329 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); -330 LOGGER.debug("", ex); -331 return; -332 -333 } -334 -335 LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); -336 LOGGER.info("Analysis Starting"); -337 final long analysisStart = System.currentTimeMillis(); -338 -339 // analysis phases -340 for (AnalysisPhase phase : AnalysisPhase.values()) { -341 final List<Analyzer> analyzerList = analyzers.get(phase); -342 -343 for (Analyzer a : analyzerList) { -344 a = initializeAnalyzer(a); -345 -346 /* need to create a copy of the collection because some of the -347 * analyzers may modify it. This prevents ConcurrentModificationExceptions. -348 * This is okay for adds/deletes because it happens per analyzer. -349 */ -350 LOGGER.debug("Begin Analyzer '{}'", a.getName()); -351 final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies); -352 for (Dependency d : dependencySet) { -353 boolean shouldAnalyze = true; -354 if (a instanceof FileTypeAnalyzer) { -355 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; -356 shouldAnalyze = fAnalyzer.accept(d.getActualFile()); -357 } -358 if (shouldAnalyze) { -359 LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath()); -360 try { -361 a.analyze(d, this); -362 } catch (AnalysisException ex) { -363 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath()); -364 LOGGER.debug("", ex); -365 } catch (Throwable ex) { -366 //final AnalysisException ax = new AnalysisException(axMsg, ex); -367 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath()); -368 LOGGER.debug("", ex); -369 } -370 } -371 } -372 } -373 } -374 for (AnalysisPhase phase : AnalysisPhase.values()) { -375 final List<Analyzer> analyzerList = analyzers.get(phase); -376 -377 for (Analyzer a : analyzerList) { -378 closeAnalyzer(a); -379 } -380 } -381 -382 LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); -383 LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart); -384 } -385 -386 /** -387 * Initializes the given analyzer. -388 * -389 * @param analyzer the analyzer to initialize -390 * @return the initialized analyzer -391 */ -392 protected Analyzer initializeAnalyzer(Analyzer analyzer) { -393 try { -394 LOGGER.debug("Initializing {}", analyzer.getName()); -395 analyzer.initialize(); -396 } catch (Throwable ex) { -397 LOGGER.error("Exception occurred initializing {}.", analyzer.getName()); -398 LOGGER.debug("", ex); -399 try { -400 analyzer.close(); -401 } catch (Throwable ex1) { -402 LOGGER.trace("", ex1); -403 } -404 } -405 return analyzer; -406 } -407 -408 /** -409 * Closes the given analyzer. -410 * -411 * @param analyzer the analyzer to close -412 */ -413 protected void closeAnalyzer(Analyzer analyzer) { -414 LOGGER.debug("Closing Analyzer '{}'", analyzer.getName()); -415 try { -416 analyzer.close(); -417 } catch (Throwable ex) { -418 LOGGER.trace("", ex); -419 } -420 } -421 -422 /** -423 * Cycles through the cached web data sources and calls update on all of them. -424 */ -425 public void doUpdates() { -426 LOGGER.info("Checking for updates"); -427 final long updateStart = System.currentTimeMillis(); -428 final UpdateService service = new UpdateService(serviceClassLoader); -429 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); -430 while (iterator.hasNext()) { -431 final CachedWebDataSource source = iterator.next(); -432 try { -433 source.update(); -434 } catch (UpdateException ex) { -435 LOGGER.warn( -436 "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities."); -437 LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex); -438 } -439 } -440 LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); -441 } -442 -443 /** -444 * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used. -445 * -446 * @return a list of Analyzers -447 */ -448 public List<Analyzer> getAnalyzers() { -449 final List<Analyzer> ret = new ArrayList<Analyzer>(); -450 for (AnalysisPhase phase : AnalysisPhase.values()) { -451 final List<Analyzer> analyzerList = analyzers.get(phase); -452 ret.addAll(analyzerList); -453 } -454 return ret; -455 } -456 -457 /** -458 * Checks all analyzers to see if an extension is supported. -459 * -460 * @param file a file extension -461 * @return true or false depending on whether or not the file extension is supported -462 */ -463 @Override -464 public boolean accept(File file) { -465 if (file == null) { -466 return false; -467 } -468 boolean scan = false; -469 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { -470 /* note, we can't break early on this loop as the analyzers need to know if -471 they have files to work on prior to initialization */ -472 scan |= a.accept(file); -473 } -474 return scan; -475 } -476 -477 /** -478 * Returns the set of file type analyzers. -479 * -480 * @return the set of file type analyzers -481 */ -482 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { -483 return this.fileTypeAnalyzers; -484 } -485 -486 /** -487 * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown. -488 * -489 * @throws NoDataException thrown if no data exists in the CPE Index -490 * @throws DatabaseException thrown if there is an exception opening the database -491 */ -492 private void ensureDataExists() throws NoDataException, DatabaseException { -493 final CveDB cve = new CveDB(); -494 try { -495 cve.open(); -496 if (!cve.dataExists()) { -497 throw new NoDataException("No documents exist"); -498 } -499 } catch (DatabaseException ex) { -500 throw new NoDataException(ex.getMessage(), ex); -501 } finally { -502 cve.close(); -503 } -504 } -505 } +129 final List<Analyzer> iterator = service.getAnalyzers(); +130 for (Analyzer a : iterator) { +131 analyzers.get(a.getAnalysisPhase()).add(a); +132 if (a instanceof FileTypeAnalyzer) { +133 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); +134 } +135 } +136 } +137 +138 /** +139 * Get the List of the analyzers for a specific phase of analysis. +140 * +141 * @param phase the phase to get the configured analyzers. +142 * @return the analyzers loaded +143 */ +144 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { +145 return analyzers.get(phase); +146 } +147 +148 /** +149 * Get the dependencies identified. +150 * +151 * @return the dependencies identified +152 */ +153 public List<Dependency> getDependencies() { +154 return dependencies; +155 } +156 +157 /** +158 * Sets the dependencies. +159 * +160 * @param dependencies the dependencies +161 */ +162 public void setDependencies(List<Dependency> dependencies) { +163 this.dependencies = dependencies; +164 } +165 +166 /** +167 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies +168 * identified are added to the dependency collection. +169 * +170 * @param paths an array of paths to files or directories to be analyzed +171 * @return the list of dependencies scanned +172 * @since v0.3.2.5 +173 */ +174 public List<Dependency> scan(String[] paths) { +175 final List<Dependency> deps = new ArrayList<Dependency>(); +176 for (String path : paths) { +177 final List<Dependency> d = scan(path); +178 if (d != null) { +179 deps.addAll(d); +180 } +181 } +182 return deps; +183 } +184 +185 /** +186 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified +187 * are added to the dependency collection. +188 * +189 * @param path the path to a file or directory to be analyzed +190 * @return the list of dependencies scanned +191 */ +192 public List<Dependency> scan(String path) { +193 final File file = new File(path); +194 return scan(file); +195 } +196 +197 /** +198 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies +199 * identified are added to the dependency collection. +200 * +201 * @param files an array of paths to files or directories to be analyzed. +202 * @return the list of dependencies +203 * @since v0.3.2.5 +204 */ +205 public List<Dependency> scan(File[] files) { +206 final List<Dependency> deps = new ArrayList<Dependency>(); +207 for (File file : files) { +208 final List<Dependency> d = scan(file); +209 if (d != null) { +210 deps.addAll(d); +211 } +212 } +213 return deps; +214 } +215 +216 /** +217 * Scans a collection of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies +218 * identified are added to the dependency collection. +219 * +220 * @param files a set of paths to files or directories to be analyzed +221 * @return the list of dependencies scanned +222 * @since v0.3.2.5 +223 */ +224 public List<Dependency> scan(Collection<File> files) { +225 final List<Dependency> deps = new ArrayList<Dependency>(); +226 for (File file : files) { +227 final List<Dependency> d = scan(file); +228 if (d != null) { +229 deps.addAll(d); +230 } +231 } +232 return deps; +233 } +234 +235 /** +236 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified +237 * are added to the dependency collection. +238 * +239 * @param file the path to a file or directory to be analyzed +240 * @return the list of dependencies scanned +241 * @since v0.3.2.4 +242 */ +243 public List<Dependency> scan(File file) { +244 if (file.exists()) { +245 if (file.isDirectory()) { +246 return scanDirectory(file); +247 } else { +248 final Dependency d = scanFile(file); +249 if (d != null) { +250 final List<Dependency> deps = new ArrayList<Dependency>(); +251 deps.add(d); +252 return deps; +253 } +254 } +255 } +256 return null; +257 } +258 +259 /** +260 * Recursively scans files and directories. Any dependencies identified are added to the dependency collection. +261 * +262 * @param dir the directory to scan +263 * @return the list of Dependency objects scanned +264 */ +265 protected List<Dependency> scanDirectory(File dir) { +266 final File[] files = dir.listFiles(); +267 final List<Dependency> deps = new ArrayList<Dependency>(); +268 if (files != null) { +269 for (File f : files) { +270 if (f.isDirectory()) { +271 final List<Dependency> d = scanDirectory(f); +272 if (d != null) { +273 deps.addAll(d); +274 } +275 } else { +276 final Dependency d = scanFile(f); +277 deps.add(d); +278 } +279 } +280 } +281 return deps; +282 } +283 +284 /** +285 * Scans a specified file. If a dependency is identified it is added to the dependency collection. +286 * +287 * @param file The file to scan +288 * @return the scanned dependency +289 */ +290 protected Dependency scanFile(File file) { +291 Dependency dependency = null; +292 if (file.isFile()) { +293 if (accept(file)) { +294 dependency = new Dependency(file); +295 dependencies.add(dependency); +296 } +297 } else { +298 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file); +299 } +300 return dependency; +301 } +302 +303 /** +304 * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via +305 * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for +306 * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the +307 * dependencies list. +308 */ +309 public void analyzeDependencies() { +310 boolean autoUpdate = true; +311 try { +312 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +313 } catch (InvalidSettingException ex) { +314 LOGGER.debug("Invalid setting for auto-update; using true."); +315 } +316 if (autoUpdate) { +317 doUpdates(); +318 } +319 +320 //need to ensure that data exists +321 try { +322 ensureDataExists(); +323 } catch (NoDataException ex) { +324 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +325 LOGGER.debug("", ex); +326 return; +327 } catch (DatabaseException ex) { +328 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +329 LOGGER.debug("", ex); +330 return; +331 +332 } +333 +334 LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); +335 LOGGER.info("Analysis Starting"); +336 final long analysisStart = System.currentTimeMillis(); +337 +338 // analysis phases +339 for (AnalysisPhase phase : AnalysisPhase.values()) { +340 final List<Analyzer> analyzerList = analyzers.get(phase); +341 +342 for (Analyzer a : analyzerList) { +343 a = initializeAnalyzer(a); +344 +345 /* need to create a copy of the collection because some of the +346 * analyzers may modify it. This prevents ConcurrentModificationExceptions. +347 * This is okay for adds/deletes because it happens per analyzer. +348 */ +349 LOGGER.debug("Begin Analyzer '{}'", a.getName()); +350 final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies); +351 for (Dependency d : dependencySet) { +352 boolean shouldAnalyze = true; +353 if (a instanceof FileTypeAnalyzer) { +354 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; +355 shouldAnalyze = fAnalyzer.accept(d.getActualFile()); +356 } +357 if (shouldAnalyze) { +358 LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath()); +359 try { +360 a.analyze(d, this); +361 } catch (AnalysisException ex) { +362 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath()); +363 LOGGER.debug("", ex); +364 } catch (Throwable ex) { +365 //final AnalysisException ax = new AnalysisException(axMsg, ex); +366 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath()); +367 LOGGER.debug("", ex); +368 } +369 } +370 } +371 } +372 } +373 for (AnalysisPhase phase : AnalysisPhase.values()) { +374 final List<Analyzer> analyzerList = analyzers.get(phase); +375 +376 for (Analyzer a : analyzerList) { +377 closeAnalyzer(a); +378 } +379 } +380 +381 LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); +382 LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart); +383 } +384 +385 /** +386 * Initializes the given analyzer. +387 * +388 * @param analyzer the analyzer to initialize +389 * @return the initialized analyzer +390 */ +391 protected Analyzer initializeAnalyzer(Analyzer analyzer) { +392 try { +393 LOGGER.debug("Initializing {}", analyzer.getName()); +394 analyzer.initialize(); +395 } catch (Throwable ex) { +396 LOGGER.error("Exception occurred initializing {}.", analyzer.getName()); +397 LOGGER.debug("", ex); +398 try { +399 analyzer.close(); +400 } catch (Throwable ex1) { +401 LOGGER.trace("", ex1); +402 } +403 } +404 return analyzer; +405 } +406 +407 /** +408 * Closes the given analyzer. +409 * +410 * @param analyzer the analyzer to close +411 */ +412 protected void closeAnalyzer(Analyzer analyzer) { +413 LOGGER.debug("Closing Analyzer '{}'", analyzer.getName()); +414 try { +415 analyzer.close(); +416 } catch (Throwable ex) { +417 LOGGER.trace("", ex); +418 } +419 } +420 +421 /** +422 * Cycles through the cached web data sources and calls update on all of them. +423 */ +424 public void doUpdates() { +425 LOGGER.info("Checking for updates"); +426 final long updateStart = System.currentTimeMillis(); +427 final UpdateService service = new UpdateService(serviceClassLoader); +428 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); +429 while (iterator.hasNext()) { +430 final CachedWebDataSource source = iterator.next(); +431 try { +432 source.update(); +433 } catch (UpdateException ex) { +434 LOGGER.warn( +435 "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities."); +436 LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex); +437 } +438 } +439 LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); +440 } +441 +442 /** +443 * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used. +444 * +445 * @return a list of Analyzers +446 */ +447 public List<Analyzer> getAnalyzers() { +448 final List<Analyzer> ret = new ArrayList<Analyzer>(); +449 for (AnalysisPhase phase : AnalysisPhase.values()) { +450 final List<Analyzer> analyzerList = analyzers.get(phase); +451 ret.addAll(analyzerList); +452 } +453 return ret; +454 } +455 +456 /** +457 * Checks all analyzers to see if an extension is supported. +458 * +459 * @param file a file extension +460 * @return true or false depending on whether or not the file extension is supported +461 */ +462 @Override +463 public boolean accept(File file) { +464 if (file == null) { +465 return false; +466 } +467 boolean scan = false; +468 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { +469 /* note, we can't break early on this loop as the analyzers need to know if +470 they have files to work on prior to initialization */ +471 scan |= a.accept(file); +472 } +473 return scan; +474 } +475 +476 /** +477 * Returns the set of file type analyzers. +478 * +479 * @return the set of file type analyzers +480 */ +481 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { +482 return this.fileTypeAnalyzers; +483 } +484 +485 /** +486 * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown. +487 * +488 * @throws NoDataException thrown if no data exists in the CPE Index +489 * @throws DatabaseException thrown if there is an exception opening the database +490 */ +491 private void ensureDataExists() throws NoDataException, DatabaseException { +492 final CveDB cve = new CveDB(); +493 try { +494 cve.open(); +495 if (!cve.dataExists()) { +496 throw new NoDataException("No documents exist"); +497 } +498 } catch (DatabaseException ex) { +499 throw new NoDataException(ex.getMessage(), ex); +500 } finally { +501 cve.close(); +502 } +503 } +504 }
      diff --git a/xref/org/owasp/dependencycheck/agent/package-frame.html b/xref/org/owasp/dependencycheck/agent/package-frame.html index c224aa7df..038470e7a 100644 --- a/xref/org/owasp/dependencycheck/agent/package-frame.html +++ b/xref/org/owasp/dependencycheck/agent/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.agent + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.agent diff --git a/xref/org/owasp/dependencycheck/agent/package-summary.html b/xref/org/owasp/dependencycheck/agent/package-summary.html index 89518c007..682059143 100644 --- a/xref/org/owasp/dependencycheck/agent/package-summary.html +++ b/xref/org/owasp/dependencycheck/agent/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.agent + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.agent diff --git a/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html index b692366ac..974fddd8b 100644 --- a/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html @@ -42,147 +42,154 @@ 34 import org.owasp.dependencycheck.utils.Settings; 35 import org.slf4j.Logger; 36 import org.slf4j.LoggerFactory; -37 -38 /** -39 * Abstract base suppression analyzer that contains methods for parsing the suppression xml file. -40 * -41 * @author Jeremy Long -42 */ -43 public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { -44 -45 /** -46 * The Logger for use throughout the class -47 */ -48 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class); -49 -50 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -51 /** -52 * Returns a list of file EXTENSIONS supported by this analyzer. -53 * -54 * @return a list of file EXTENSIONS supported by this analyzer. -55 */ -56 public Set<String> getSupportedExtensions() { -57 return null; -58 } -59 -60 //</editor-fold> -61 /** -62 * The initialize method loads the suppression XML file. -63 * -64 * @throws Exception thrown if there is an exception -65 */ -66 @Override -67 public void initialize() throws Exception { -68 super.initialize(); -69 loadSuppressionData(); -70 } -71 -72 /** -73 * The list of suppression rules -74 */ -75 private List<SuppressionRule> rules; -76 -77 /** -78 * Get the value of rules. -79 * -80 * @return the value of rules -81 */ -82 public List<SuppressionRule> getRules() { -83 return rules; -84 } -85 -86 /** -87 * Set the value of rules. -88 * -89 * @param rules new value of rules -90 */ -91 public void setRules(List<SuppressionRule> rules) { -92 this.rules = rules; -93 } -94 -95 /** -96 * Loads the suppression rules file. -97 * -98 * @throws SuppressionParseException thrown if the XML cannot be parsed. -99 */ -100 private void loadSuppressionData() throws SuppressionParseException { -101 final SuppressionParser parser = new SuppressionParser(); -102 File file = null; -103 try { -104 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); -105 } catch (SuppressionParseException ex) { -106 LOGGER.debug("Unable to parse the base suppression data file", ex); -107 } -108 final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); -109 if (suppressionFilePath == null) { -110 return; -111 } -112 boolean deleteTempFile = false; -113 try { -114 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); -115 if (uriRx.matcher(suppressionFilePath).matches()) { -116 deleteTempFile = true; -117 file = FileUtils.getTempFile("suppression", "xml"); -118 final URL url = new URL(suppressionFilePath); -119 try { -120 Downloader.fetchFile(url, file, false); -121 } catch (DownloadFailedException ex) { -122 Downloader.fetchFile(url, file, true); -123 } -124 } else { -125 file = new File(suppressionFilePath); -126 if (!file.exists()) { -127 final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); -128 if (suppressionsFromClasspath != null) { -129 deleteTempFile = true; -130 file = FileUtils.getTempFile("suppression", "xml"); -131 try { -132 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); -133 } catch (IOException ex) { -134 throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); -135 } -136 } -137 } -138 } -139 -140 if (file != null) { -141 try { -142 //rules = parser.parseSuppressionRules(file); -143 rules.addAll(parser.parseSuppressionRules(file)); -144 LOGGER.debug("{} suppression rules were loaded.", rules.size()); -145 } catch (SuppressionParseException ex) { -146 LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); -147 LOGGER.warn(ex.getMessage()); -148 LOGGER.debug("", ex); -149 throw ex; -150 } -151 } -152 } catch (DownloadFailedException ex) { -153 throwSuppressionParseException("Unable to fetch the configured suppression file", ex); -154 } catch (MalformedURLException ex) { -155 throwSuppressionParseException("Configured suppression file has an invalid URL", ex); -156 } catch (IOException ex) { -157 throwSuppressionParseException("Unable to create temp file for suppressions", ex); -158 } finally { -159 if (deleteTempFile && file != null) { -160 FileUtils.delete(file); -161 } -162 } -163 } -164 -165 /** -166 * Utility method to throw parse exceptions. -167 * -168 * @param message the exception message -169 * @param exception the cause of the exception -170 * @throws SuppressionParseException throws the generated SuppressionParseException -171 */ -172 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { -173 LOGGER.warn(message); -174 LOGGER.debug("", exception); -175 throw new SuppressionParseException(message, exception); -176 } -177 } +37 import org.xml.sax.SAXException; +38 +39 /** +40 * Abstract base suppression analyzer that contains methods for parsing the +41 * suppression xml file. +42 * +43 * @author Jeremy Long +44 */ +45 public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { +46 +47 /** +48 * The Logger for use throughout the class +49 */ +50 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class); +51 +52 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +53 /** +54 * Returns a list of file EXTENSIONS supported by this analyzer. +55 * +56 * @return a list of file EXTENSIONS supported by this analyzer. +57 */ +58 public Set<String> getSupportedExtensions() { +59 return null; +60 } +61 +62 //</editor-fold> +63 /** +64 * The initialize method loads the suppression XML file. +65 * +66 * @throws Exception thrown if there is an exception +67 */ +68 @Override +69 public void initialize() throws Exception { +70 super.initialize(); +71 loadSuppressionData(); +72 } +73 +74 /** +75 * The list of suppression rules +76 */ +77 private List<SuppressionRule> rules; +78 +79 /** +80 * Get the value of rules. +81 * +82 * @return the value of rules +83 */ +84 public List<SuppressionRule> getRules() { +85 return rules; +86 } +87 +88 /** +89 * Set the value of rules. +90 * +91 * @param rules new value of rules +92 */ +93 public void setRules(List<SuppressionRule> rules) { +94 this.rules = rules; +95 } +96 +97 /** +98 * Loads the suppression rules file. +99 * +100 * @throws SuppressionParseException thrown if the XML cannot be parsed. +101 */ +102 private void loadSuppressionData() throws SuppressionParseException { +103 final SuppressionParser parser = new SuppressionParser(); +104 File file = null; +105 try { +106 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); +107 } catch (SuppressionParseException ex) { +108 LOGGER.error("Unable to parse the base suppression data file"); +109 LOGGER.debug("Unable to parse the base suppression data file", ex); +110 } catch (SAXException ex) { +111 LOGGER.error("Unable to parse the base suppression data file"); +112 LOGGER.debug("Unable to parse the base suppression data file", ex); +113 } +114 final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); +115 if (suppressionFilePath == null) { +116 return; +117 } +118 boolean deleteTempFile = false; +119 try { +120 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); +121 if (uriRx.matcher(suppressionFilePath).matches()) { +122 deleteTempFile = true; +123 file = FileUtils.getTempFile("suppression", "xml"); +124 final URL url = new URL(suppressionFilePath); +125 try { +126 Downloader.fetchFile(url, file, false); +127 } catch (DownloadFailedException ex) { +128 Downloader.fetchFile(url, file, true); +129 } +130 } else { +131 file = new File(suppressionFilePath); +132 if (!file.exists()) { +133 final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); +134 if (suppressionsFromClasspath != null) { +135 deleteTempFile = true; +136 file = FileUtils.getTempFile("suppression", "xml"); +137 try { +138 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); +139 } catch (IOException ex) { +140 throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); +141 } +142 } +143 } +144 } +145 +146 if (file != null) { +147 try { +148 //rules = parser.parseSuppressionRules(file); +149 rules.addAll(parser.parseSuppressionRules(file)); +150 LOGGER.debug("{} suppression rules were loaded.", rules.size()); +151 } catch (SuppressionParseException ex) { +152 LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); +153 LOGGER.warn(ex.getMessage()); +154 LOGGER.debug("", ex); +155 throw ex; +156 } +157 } +158 } catch (DownloadFailedException ex) { +159 throwSuppressionParseException("Unable to fetch the configured suppression file", ex); +160 } catch (MalformedURLException ex) { +161 throwSuppressionParseException("Configured suppression file has an invalid URL", ex); +162 } catch (IOException ex) { +163 throwSuppressionParseException("Unable to create temp file for suppressions", ex); +164 } finally { +165 if (deleteTempFile && file != null) { +166 FileUtils.delete(file); +167 } +168 } +169 } +170 +171 /** +172 * Utility method to throw parse exceptions. +173 * +174 * @param message the exception message +175 * @param exception the cause of the exception +176 * @throws SuppressionParseException throws the generated +177 * SuppressionParseException +178 */ +179 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { +180 LOGGER.warn(message); +181 LOGGER.debug("", exception); +182 throw new SuppressionParseException(message, exception); +183 } +184 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/AnalyzerService.html b/xref/org/owasp/dependencycheck/analyzer/AnalyzerService.html index 2c7cc2f90..05caba69a 100644 --- a/xref/org/owasp/dependencycheck/analyzer/AnalyzerService.html +++ b/xref/org/owasp/dependencycheck/analyzer/AnalyzerService.html @@ -25,40 +25,65 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.util.Iterator; -21 import java.util.ServiceLoader; -22 -23 /** -24 * The Analyzer Service Loader. This class loads all services that implement -25 * org.owasp.dependencycheck.analyzer.Analyzer. -26 * -27 * @author Jeremy Long -28 */ -29 public class AnalyzerService { -30 -31 /** -32 * The service loader for analyzers. -33 */ -34 private final ServiceLoader<Analyzer> loader; -35 -36 /** -37 * Creates a new instance of AnalyzerService. -38 * -39 * @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services -40 */ -41 public AnalyzerService(ClassLoader classLoader) { -42 loader = ServiceLoader.load(Analyzer.class, classLoader); -43 } +20 import java.util.ArrayList; +21 import java.util.Iterator; +22 import java.util.List; +23 import java.util.ServiceLoader; +24 import org.owasp.dependencycheck.utils.InvalidSettingException; +25 import org.owasp.dependencycheck.utils.Settings; +26 import org.slf4j.LoggerFactory; +27 +28 /** +29 * The Analyzer Service Loader. This class loads all services that implement +30 * org.owasp.dependencycheck.analyzer.Analyzer. +31 * +32 * @author Jeremy Long +33 */ +34 public class AnalyzerService { +35 /** +36 * The Logger for use throughout the class. +37 */ +38 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnalyzerService.class); +39 +40 /** +41 * The service loader for analyzers. +42 */ +43 private final ServiceLoader<Analyzer> service; 44 45 /** -46 * Returns an Iterator for all instances of the Analyzer interface. +46 * Creates a new instance of AnalyzerService. 47 * -48 * @return an iterator of Analyzers. +48 * @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services 49 */ -50 public Iterator<Analyzer> getAnalyzers() { -51 return loader.iterator(); +50 public AnalyzerService(ClassLoader classLoader) { +51 service = ServiceLoader.load(Analyzer.class, classLoader); 52 } -53 } +53 +54 /** +55 * Returns a list of all instances of the Analyzer interface. +56 * +57 * @return a list of Analyzers. +58 */ +59 public List<Analyzer> getAnalyzers() { +60 final List<Analyzer> analyzers = new ArrayList<Analyzer>(); +61 final Iterator<Analyzer> iterator = service.iterator(); +62 boolean experimentalEnabled = false; +63 try { +64 experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); +65 } catch (InvalidSettingException ex) { +66 LOGGER.error("invalide experimental setting", ex); +67 } +68 while (iterator.hasNext()) { +69 final Analyzer a = iterator.next(); +70 if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) { +71 continue; +72 } +73 LOGGER.debug("Loaded Analyzer {}", a.getName()); +74 analyzers.add(a); +75 } +76 return analyzers; +77 } +78 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html index 2410e0932..7561a4627 100644 --- a/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html @@ -38,204 +38,204 @@ 30 import java.io.File; 31 import java.io.FileFilter; 32 import java.io.IOException; -33 import java.util.ArrayList; -34 import java.util.List; -35 import java.util.regex.Matcher; -36 import java.util.regex.Pattern; -37 -38 /** -39 * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed, -40 * assuming they are generated by Autoconf, and contain certain special package descriptor variables. -41 * -42 * @author Dale Visser -43 * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a> -44 */ -45 public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { -46 -47 /** -48 * Autoconf output filename. -49 */ -50 private static final String CONFIGURE = "configure"; -51 -52 /** -53 * Autoconf input filename. -54 */ -55 private static final String CONFIGURE_IN = "configure.in"; -56 -57 /** -58 * Autoconf input filename. -59 */ -60 private static final String CONFIGURE_AC = "configure.ac"; -61 -62 /** -63 * The name of the analyzer. -64 */ -65 private static final String ANALYZER_NAME = "Autoconf Analyzer"; -66 -67 /** -68 * The phase that this analyzer is intended to run in. -69 */ -70 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -71 -72 /** -73 * The set of file extensions supported by this analyzer. -74 */ -75 private static final String[] EXTENSIONS = {"ac", "in"}; -76 -77 /** -78 * Matches AC_INIT variables in the output configure script. -79 */ -80 private static final Pattern PACKAGE_VAR = Pattern.compile( -81 "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); -82 -83 /** -84 * Matches AC_INIT statement in configure.ac file. -85 */ -86 private static final Pattern AC_INIT_PATTERN; -87 -88 static { -89 // each instance of param or sep_param has a capture group -90 final String param = "\\[{0,2}(.+?)\\]{0,2}"; -91 final String sepParam = "\\s*,\\s*" + param; -92 // Group 1: Package -93 // Group 2: Version -94 // Group 3: optional -95 // Group 4: Bug report address (if it exists) -96 // Group 5: optional -97 // Group 6: Tarname (if it exists) -98 // Group 7: optional -99 // Group 8: URL (if it exists) -100 AC_INIT_PATTERN = Pattern.compile(String.format( -101 "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam, -102 sepParam, sepParam, sepParam), Pattern.DOTALL -103 | Pattern.CASE_INSENSITIVE); -104 } -105 -106 /** -107 * The file filter used to determine which files this analyzer supports. -108 */ -109 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions( -110 EXTENSIONS).build(); -111 -112 /** -113 * Returns the FileFilter -114 * -115 * @return the FileFilter -116 */ -117 @Override -118 protected FileFilter getFileFilter() { -119 return FILTER; -120 } -121 -122 /** -123 * Returns the name of the analyzer. -124 * -125 * @return the name of the analyzer. -126 */ -127 @Override -128 public String getName() { -129 return ANALYZER_NAME; -130 } -131 -132 /** -133 * Returns the phase that the analyzer is intended to run in. -134 * -135 * @return the phase that the analyzer is intended to run in. -136 */ -137 @Override -138 public AnalysisPhase getAnalysisPhase() { -139 return ANALYSIS_PHASE; -140 } -141 -142 /** -143 * Returns the key used in the properties file to reference the analyzer's enabled property. -144 * -145 * @return the analyzer's enabled property setting key -146 */ -147 @Override -148 protected String getAnalyzerEnabledSettingKey() { -149 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; -150 } -151 -152 @Override -153 protected void analyzeFileType(Dependency dependency, Engine engine) -154 throws AnalysisException { -155 final File actualFile = dependency.getActualFile(); -156 final String name = actualFile.getName(); -157 if (name.startsWith(CONFIGURE)) { -158 final File parent = actualFile.getParentFile(); -159 final String parentName = parent.getName(); -160 dependency.setDisplayFileName(parentName + "/" + name); -161 final boolean isOutputScript = CONFIGURE.equals(name); -162 if (isOutputScript || CONFIGURE_AC.equals(name) -163 || CONFIGURE_IN.equals(name)) { -164 final String contents = getFileContents(actualFile); -165 if (!contents.isEmpty()) { -166 if (isOutputScript) { -167 extractConfigureScriptEvidence(dependency, name, -168 contents); -169 } else { -170 gatherEvidence(dependency, name, contents); -171 } -172 } -173 } -174 } else { -175 // copy, alter and set in case some other thread is iterating over -176 final List<Dependency> dependencies = new ArrayList<Dependency>( -177 engine.getDependencies()); -178 dependencies.remove(dependency); -179 engine.setDependencies(dependencies); -180 } -181 } -182 -183 /** -184 * Extracts evidence from the configuration. -185 * -186 * @param dependency the dependency being analyzed -187 * @param name the name of the source of evidence -188 * @param contents the contents to analyze for evidence -189 */ -190 private void extractConfigureScriptEvidence(Dependency dependency, -191 final String name, final String contents) { -192 final Matcher matcher = PACKAGE_VAR.matcher(contents); -193 while (matcher.find()) { -194 final String variable = matcher.group(1); -195 final String value = matcher.group(2); -196 if (!value.isEmpty()) { -197 if (variable.endsWith("NAME")) { -198 dependency.getProductEvidence().addEvidence(name, variable, -199 value, Confidence.HIGHEST); -200 } else if ("VERSION".equals(variable)) { -201 dependency.getVersionEvidence().addEvidence(name, variable, -202 value, Confidence.HIGHEST); -203 } else if ("BUGREPORT".equals(variable)) { -204 dependency.getVendorEvidence().addEvidence(name, variable, -205 value, Confidence.HIGH); -206 } else if ("URL".equals(variable)) { -207 dependency.getVendorEvidence().addEvidence(name, variable, -208 value, Confidence.HIGH); -209 } -210 } -211 } -212 } -213 -214 /** -215 * Retrieves the contents of a given file. -216 * -217 * @param actualFile the file to read -218 * @return the contents of the file -219 * @throws AnalysisException thrown if there is an IO Exception -220 */ -221 private String getFileContents(final File actualFile) -222 throws AnalysisException { -223 String contents = ""; -224 try { -225 contents = FileUtils.readFileToString(actualFile).trim(); -226 } catch (IOException e) { -227 throw new AnalysisException( -228 "Problem occurred while reading dependency file.", e); -229 } -230 return contents; +33 import java.nio.charset.Charset; +34 import java.util.ArrayList; +35 import java.util.List; +36 import java.util.regex.Matcher; +37 import java.util.regex.Pattern; +38 +39 /** +40 * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed, +41 * assuming they are generated by Autoconf, and contain certain special package descriptor variables. +42 * +43 * @author Dale Visser +44 * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a> +45 */ +46 @Experimental +47 public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { +48 +49 /** +50 * Autoconf output filename. +51 */ +52 private static final String CONFIGURE = "configure"; +53 +54 /** +55 * Autoconf input filename. +56 */ +57 private static final String CONFIGURE_IN = "configure.in"; +58 +59 /** +60 * Autoconf input filename. +61 */ +62 private static final String CONFIGURE_AC = "configure.ac"; +63 +64 /** +65 * The name of the analyzer. +66 */ +67 private static final String ANALYZER_NAME = "Autoconf Analyzer"; +68 +69 /** +70 * The phase that this analyzer is intended to run in. +71 */ +72 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +73 +74 /** +75 * The set of file extensions supported by this analyzer. +76 */ +77 private static final String[] EXTENSIONS = {"ac", "in"}; +78 +79 /** +80 * Matches AC_INIT variables in the output configure script. +81 */ +82 private static final Pattern PACKAGE_VAR = Pattern.compile( +83 "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); +84 +85 /** +86 * Matches AC_INIT statement in configure.ac file. +87 */ +88 private static final Pattern AC_INIT_PATTERN; +89 +90 static { +91 // each instance of param or sep_param has a capture group +92 final String param = "\\[{0,2}(.+?)\\]{0,2}"; +93 final String sepParam = "\\s*,\\s*" + param; +94 // Group 1: Package +95 // Group 2: Version +96 // Group 3: optional +97 // Group 4: Bug report address (if it exists) +98 // Group 5: optional +99 // Group 6: Tarname (if it exists) +100 // Group 7: optional +101 // Group 8: URL (if it exists) +102 AC_INIT_PATTERN = Pattern.compile(String.format( +103 "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam, +104 sepParam, sepParam, sepParam), Pattern.DOTALL +105 | Pattern.CASE_INSENSITIVE); +106 } +107 +108 /** +109 * The file filter used to determine which files this analyzer supports. +110 */ +111 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions( +112 EXTENSIONS).build(); +113 +114 /** +115 * Returns the FileFilter +116 * +117 * @return the FileFilter +118 */ +119 @Override +120 protected FileFilter getFileFilter() { +121 return FILTER; +122 } +123 +124 /** +125 * Returns the name of the analyzer. +126 * +127 * @return the name of the analyzer. +128 */ +129 @Override +130 public String getName() { +131 return ANALYZER_NAME; +132 } +133 +134 /** +135 * Returns the phase that the analyzer is intended to run in. +136 * +137 * @return the phase that the analyzer is intended to run in. +138 */ +139 @Override +140 public AnalysisPhase getAnalysisPhase() { +141 return ANALYSIS_PHASE; +142 } +143 +144 /** +145 * Returns the key used in the properties file to reference the analyzer's enabled property. +146 * +147 * @return the analyzer's enabled property setting key +148 */ +149 @Override +150 protected String getAnalyzerEnabledSettingKey() { +151 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; +152 } +153 +154 @Override +155 protected void analyzeFileType(Dependency dependency, Engine engine) +156 throws AnalysisException { +157 final File actualFile = dependency.getActualFile(); +158 final String name = actualFile.getName(); +159 if (name.startsWith(CONFIGURE)) { +160 final File parent = actualFile.getParentFile(); +161 final String parentName = parent.getName(); +162 dependency.setDisplayFileName(parentName + "/" + name); +163 final boolean isOutputScript = CONFIGURE.equals(name); +164 if (isOutputScript || CONFIGURE_AC.equals(name) +165 || CONFIGURE_IN.equals(name)) { +166 final String contents = getFileContents(actualFile); +167 if (!contents.isEmpty()) { +168 if (isOutputScript) { +169 extractConfigureScriptEvidence(dependency, name, +170 contents); +171 } else { +172 gatherEvidence(dependency, name, contents); +173 } +174 } +175 } +176 } else { +177 // copy, alter and set in case some other thread is iterating over +178 final List<Dependency> dependencies = new ArrayList<Dependency>( +179 engine.getDependencies()); +180 dependencies.remove(dependency); +181 engine.setDependencies(dependencies); +182 } +183 } +184 +185 /** +186 * Extracts evidence from the configuration. +187 * +188 * @param dependency the dependency being analyzed +189 * @param name the name of the source of evidence +190 * @param contents the contents to analyze for evidence +191 */ +192 private void extractConfigureScriptEvidence(Dependency dependency, +193 final String name, final String contents) { +194 final Matcher matcher = PACKAGE_VAR.matcher(contents); +195 while (matcher.find()) { +196 final String variable = matcher.group(1); +197 final String value = matcher.group(2); +198 if (!value.isEmpty()) { +199 if (variable.endsWith("NAME")) { +200 dependency.getProductEvidence().addEvidence(name, variable, +201 value, Confidence.HIGHEST); +202 } else if ("VERSION".equals(variable)) { +203 dependency.getVersionEvidence().addEvidence(name, variable, +204 value, Confidence.HIGHEST); +205 } else if ("BUGREPORT".equals(variable)) { +206 dependency.getVendorEvidence().addEvidence(name, variable, +207 value, Confidence.HIGH); +208 } else if ("URL".equals(variable)) { +209 dependency.getVendorEvidence().addEvidence(name, variable, +210 value, Confidence.HIGH); +211 } +212 } +213 } +214 } +215 +216 /** +217 * Retrieves the contents of a given file. +218 * +219 * @param actualFile the file to read +220 * @return the contents of the file +221 * @throws AnalysisException thrown if there is an IO Exception +222 */ +223 private String getFileContents(final File actualFile) +224 throws AnalysisException { +225 try { +226 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); +227 } catch (IOException e) { +228 throw new AnalysisException( +229 "Problem occurred while reading dependency file.", e); +230 } 231 } 232 233 /** diff --git a/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html index df6dc23a0..f5f3f1e81 100644 --- a/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html @@ -41,208 +41,210 @@ 33 import java.io.FileFilter; 34 import java.io.IOException; 35 import java.io.UnsupportedEncodingException; -36 import java.security.MessageDigest; -37 import java.security.NoSuchAlgorithmException; -38 import java.util.regex.Matcher; -39 import java.util.regex.Pattern; -40 -41 /** -42 * <p> -43 * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p> -44 * <p> -45 * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version -46 * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert -47 * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be -48 * identified.</p> -49 * -50 * @author Dale Visser -51 */ -52 public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { -53 -54 /** -55 * The logger. -56 */ -57 private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class); -58 -59 /** -60 * Used when compiling file scanning regex patterns. -61 */ -62 private static final int REGEX_OPTIONS = Pattern.DOTALL -63 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE; -64 -65 /** -66 * Regex to extract the product information. -67 */ -68 private static final Pattern PROJECT = Pattern.compile( -69 "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS); -70 -71 /** -72 * Regex to extract product and version information. -73 * -74 * Group 1: Product +36 import java.nio.charset.Charset; +37 import java.security.MessageDigest; +38 import java.security.NoSuchAlgorithmException; +39 import java.util.regex.Matcher; +40 import java.util.regex.Pattern; +41 +42 /** +43 * <p> +44 * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p> +45 * <p> +46 * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version +47 * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert +48 * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be +49 * identified.</p> +50 * +51 * @author Dale Visser +52 */ +53 @Experimental +54 public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { +55 +56 /** +57 * The logger. +58 */ +59 private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class); +60 +61 /** +62 * Used when compiling file scanning regex patterns. +63 */ +64 private static final int REGEX_OPTIONS = Pattern.DOTALL +65 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE; +66 +67 /** +68 * Regex to extract the product information. +69 */ +70 private static final Pattern PROJECT = Pattern.compile( +71 "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS); +72 +73 /** +74 * Regex to extract product and version information. 75 * -76 * Group 2: Version -77 */ -78 private static final Pattern SET_VERSION = Pattern -79 .compile( -80 "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)", -81 REGEX_OPTIONS); -82 -83 /** -84 * Detects files that can be analyzed. -85 */ -86 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake") -87 .addFilenames("CMakeLists.txt").build(); -88 -89 /** -90 * A reference to SHA1 message digest. -91 */ -92 private static MessageDigest sha1 = null; -93 -94 static { -95 try { -96 sha1 = MessageDigest.getInstance("SHA1"); -97 } catch (NoSuchAlgorithmException e) { -98 LOGGER.error(e.getMessage()); -99 } -100 } -101 -102 /** -103 * Returns the name of the CMake analyzer. -104 * -105 * @return the name of the analyzer +76 * Group 1: Product +77 * +78 * Group 2: Version +79 */ +80 private static final Pattern SET_VERSION = Pattern +81 .compile( +82 "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)", +83 REGEX_OPTIONS); +84 +85 /** +86 * Detects files that can be analyzed. +87 */ +88 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake") +89 .addFilenames("CMakeLists.txt").build(); +90 +91 /** +92 * A reference to SHA1 message digest. +93 */ +94 private static MessageDigest sha1 = null; +95 +96 static { +97 try { +98 sha1 = MessageDigest.getInstance("SHA1"); +99 } catch (NoSuchAlgorithmException e) { +100 LOGGER.error(e.getMessage()); +101 } +102 } +103 +104 /** +105 * Returns the name of the CMake analyzer. 106 * -107 */ -108 @Override -109 public String getName() { -110 return "CMake Analyzer"; -111 } -112 -113 /** -114 * Tell that we are used for information collection. -115 * -116 * @return INFORMATION_COLLECTION -117 */ -118 @Override -119 public AnalysisPhase getAnalysisPhase() { -120 return AnalysisPhase.INFORMATION_COLLECTION; -121 } -122 -123 /** -124 * Returns the set of supported file extensions. -125 * -126 * @return the set of supported file extensions -127 */ -128 @Override -129 protected FileFilter getFileFilter() { -130 return FILTER; -131 } -132 -133 /** -134 * No-op initializer implementation. -135 * -136 * @throws Exception never thrown -137 */ -138 @Override -139 protected void initializeFileTypeAnalyzer() throws Exception { -140 // Nothing to do here. -141 } -142 -143 /** -144 * Analyzes python packages and adds evidence to the dependency. -145 * -146 * @param dependency the dependency being analyzed -147 * @param engine the engine being used to perform the scan -148 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency -149 */ -150 @Override -151 protected void analyzeFileType(Dependency dependency, Engine engine) -152 throws AnalysisException { -153 final File file = dependency.getActualFile(); -154 final String parentName = file.getParentFile().getName(); -155 final String name = file.getName(); -156 dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name)); -157 String contents; -158 try { -159 contents = FileUtils.readFileToString(file).trim(); -160 } catch (IOException e) { -161 throw new AnalysisException( -162 "Problem occurred while reading dependency file.", e); -163 } -164 -165 if (StringUtils.isNotBlank(contents)) { -166 final Matcher m = PROJECT.matcher(contents); -167 int count = 0; -168 while (m.find()) { -169 count++; -170 LOGGER.debug(String.format( -171 "Found project command match with %d groups: %s", -172 m.groupCount(), m.group(0))); -173 final String group = m.group(1); -174 LOGGER.debug("Group 1: " + group); -175 dependency.getProductEvidence().addEvidence(name, "Project", -176 group, Confidence.HIGH); -177 } -178 LOGGER.debug("Found {} matches.", count); -179 analyzeSetVersionCommand(dependency, engine, contents); -180 } -181 } -182 -183 /** -184 * Extracts the version information from the contents. If more then one version is found additional dependencies are added to -185 * the dependency list. -186 * -187 * @param dependency the dependency being analyzed -188 * @param engine the dependency-check engine -189 * @param contents the version information -190 */ -191 private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) { -192 Dependency currentDep = dependency; -193 -194 final Matcher m = SET_VERSION.matcher(contents); -195 int count = 0; -196 while (m.find()) { -197 count++; -198 LOGGER.debug("Found project command match with {} groups: {}", -199 m.groupCount(), m.group(0)); -200 String product = m.group(1); -201 final String version = m.group(2); -202 LOGGER.debug("Group 1: " + product); -203 LOGGER.debug("Group 2: " + version); -204 final String aliasPrefix = "ALIASOF_"; -205 if (product.startsWith(aliasPrefix)) { -206 product = product.replaceFirst(aliasPrefix, ""); -207 } -208 if (count > 1) { -209 //TODO - refactor so we do not assign to the parameter (checkstyle) -210 currentDep = new Dependency(dependency.getActualFile()); -211 currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product)); -212 final String filePath = String.format("%s:%s", dependency.getFilePath(), product); -213 currentDep.setFilePath(filePath); -214 -215 byte[] path; -216 try { -217 path = filePath.getBytes("UTF-8"); -218 } catch (UnsupportedEncodingException ex) { -219 path = filePath.getBytes(); -220 } -221 currentDep.setSha1sum(Checksum.getHex(sha1.digest(path))); -222 engine.getDependencies().add(currentDep); -223 } -224 final String source = currentDep.getDisplayFileName(); -225 currentDep.getProductEvidence().addEvidence(source, "Product", -226 product, Confidence.MEDIUM); -227 currentDep.getVersionEvidence().addEvidence(source, "Version", -228 version, Confidence.MEDIUM); -229 } -230 LOGGER.debug(String.format("Found %d matches.", count)); -231 } -232 -233 @Override -234 protected String getAnalyzerEnabledSettingKey() { -235 return Settings.KEYS.ANALYZER_CMAKE_ENABLED; -236 } -237 } +107 * @return the name of the analyzer +108 * +109 */ +110 @Override +111 public String getName() { +112 return "CMake Analyzer"; +113 } +114 +115 /** +116 * Tell that we are used for information collection. +117 * +118 * @return INFORMATION_COLLECTION +119 */ +120 @Override +121 public AnalysisPhase getAnalysisPhase() { +122 return AnalysisPhase.INFORMATION_COLLECTION; +123 } +124 +125 /** +126 * Returns the set of supported file extensions. +127 * +128 * @return the set of supported file extensions +129 */ +130 @Override +131 protected FileFilter getFileFilter() { +132 return FILTER; +133 } +134 +135 /** +136 * No-op initializer implementation. +137 * +138 * @throws Exception never thrown +139 */ +140 @Override +141 protected void initializeFileTypeAnalyzer() throws Exception { +142 // Nothing to do here. +143 } +144 +145 /** +146 * Analyzes python packages and adds evidence to the dependency. +147 * +148 * @param dependency the dependency being analyzed +149 * @param engine the engine being used to perform the scan +150 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency +151 */ +152 @Override +153 protected void analyzeFileType(Dependency dependency, Engine engine) +154 throws AnalysisException { +155 final File file = dependency.getActualFile(); +156 final String parentName = file.getParentFile().getName(); +157 final String name = file.getName(); +158 dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name)); +159 String contents; +160 try { +161 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); +162 } catch (IOException e) { +163 throw new AnalysisException( +164 "Problem occurred while reading dependency file.", e); +165 } +166 +167 if (StringUtils.isNotBlank(contents)) { +168 final Matcher m = PROJECT.matcher(contents); +169 int count = 0; +170 while (m.find()) { +171 count++; +172 LOGGER.debug(String.format( +173 "Found project command match with %d groups: %s", +174 m.groupCount(), m.group(0))); +175 final String group = m.group(1); +176 LOGGER.debug("Group 1: " + group); +177 dependency.getProductEvidence().addEvidence(name, "Project", +178 group, Confidence.HIGH); +179 } +180 LOGGER.debug("Found {} matches.", count); +181 analyzeSetVersionCommand(dependency, engine, contents); +182 } +183 } +184 +185 /** +186 * Extracts the version information from the contents. If more then one version is found additional dependencies are added to +187 * the dependency list. +188 * +189 * @param dependency the dependency being analyzed +190 * @param engine the dependency-check engine +191 * @param contents the version information +192 */ +193 private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) { +194 Dependency currentDep = dependency; +195 +196 final Matcher m = SET_VERSION.matcher(contents); +197 int count = 0; +198 while (m.find()) { +199 count++; +200 LOGGER.debug("Found project command match with {} groups: {}", +201 m.groupCount(), m.group(0)); +202 String product = m.group(1); +203 final String version = m.group(2); +204 LOGGER.debug("Group 1: " + product); +205 LOGGER.debug("Group 2: " + version); +206 final String aliasPrefix = "ALIASOF_"; +207 if (product.startsWith(aliasPrefix)) { +208 product = product.replaceFirst(aliasPrefix, ""); +209 } +210 if (count > 1) { +211 //TODO - refactor so we do not assign to the parameter (checkstyle) +212 currentDep = new Dependency(dependency.getActualFile()); +213 currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product)); +214 final String filePath = String.format("%s:%s", dependency.getFilePath(), product); +215 currentDep.setFilePath(filePath); +216 +217 byte[] path; +218 try { +219 path = filePath.getBytes("UTF-8"); +220 } catch (UnsupportedEncodingException ex) { +221 path = filePath.getBytes(); +222 } +223 currentDep.setSha1sum(Checksum.getHex(sha1.digest(path))); +224 engine.getDependencies().add(currentDep); +225 } +226 final String source = currentDep.getDisplayFileName(); +227 currentDep.getProductEvidence().addEvidence(source, "Product", +228 product, Confidence.MEDIUM); +229 currentDep.getVersionEvidence().addEvidence(source, "Version", +230 version, Confidence.MEDIUM); +231 } +232 LOGGER.debug(String.format("Found %d matches.", count)); +233 } +234 +235 @Override +236 protected String getAnalyzerEnabledSettingKey() { +237 return Settings.KEYS.ANALYZER_CMAKE_ENABLED; +238 } +239 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html index 00fd6e53d..c20446fa5 100644 --- a/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html @@ -59,726 +59,756 @@ 51 import org.slf4j.LoggerFactory; 52 53 /** -54 * CPEAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated CPE. It uses -55 * the evidence contained within the dependency to search the Lucene index. -56 * -57 * @author Jeremy Long -58 */ -59 public class CPEAnalyzer implements Analyzer { -60 -61 /** -62 * The Logger. -63 */ -64 private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class); -65 /** -66 * The maximum number of query results to return. -67 */ -68 static final int MAX_QUERY_RESULTS = 25; -69 /** -70 * The weighting boost to give terms when constructing the Lucene query. -71 */ -72 static final String WEIGHTING_BOOST = "^5"; -73 /** -74 * A string representation of a regular expression defining characters utilized within the CPE Names. -75 */ -76 static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]"; -77 /** -78 * A string representation of a regular expression used to remove all but alpha characters. -79 */ -80 static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*"; -81 /** -82 * The additional size to add to a new StringBuilder to account for extra data that will be written into the string. -83 */ -84 static final int STRING_BUILDER_BUFFER = 20; -85 /** -86 * The CPE in memory index. +54 * CPEAnalyzer is a utility class that takes a project dependency and attempts +55 * to discern if there is an associated CPE. It uses the evidence contained +56 * within the dependency to search the Lucene index. +57 * +58 * @author Jeremy Long +59 */ +60 public class CPEAnalyzer implements Analyzer { +61 +62 /** +63 * The Logger. +64 */ +65 private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class); +66 /** +67 * The maximum number of query results to return. +68 */ +69 static final int MAX_QUERY_RESULTS = 25; +70 /** +71 * The weighting boost to give terms when constructing the Lucene query. +72 */ +73 static final String WEIGHTING_BOOST = "^5"; +74 /** +75 * A string representation of a regular expression defining characters +76 * utilized within the CPE Names. +77 */ +78 static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]"; +79 /** +80 * A string representation of a regular expression used to remove all but +81 * alpha characters. +82 */ +83 static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*"; +84 /** +85 * The additional size to add to a new StringBuilder to account for extra +86 * data that will be written into the string. 87 */ -88 private CpeMemoryIndex cpe; +88 static final int STRING_BUILDER_BUFFER = 20; 89 /** -90 * The CVE Database. +90 * The CPE in memory index. 91 */ -92 private CveDB cve; -93 -94 /** -95 * The URL to perform a search of the NVD CVE data at NIST. -96 */ -97 public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s"; -98 -99 /** -100 * Returns the name of this analyzer. -101 * -102 * @return the name of this analyzer. -103 */ -104 @Override -105 public String getName() { -106 return "CPE Analyzer"; -107 } -108 -109 /** -110 * Returns the analysis phase that this analyzer should run in. -111 * -112 * @return the analysis phase that this analyzer should run in. -113 */ -114 @Override -115 public AnalysisPhase getAnalysisPhase() { -116 return AnalysisPhase.IDENTIFIER_ANALYSIS; -117 } -118 -119 /** -120 * Creates the CPE Lucene Index. -121 * -122 * @throws Exception is thrown if there is an issue opening the index. -123 */ -124 @Override -125 public void initialize() throws Exception { -126 this.open(); -127 } -128 -129 /** -130 * Opens the data source. -131 * -132 * @throws IOException when the Lucene directory to be queried does not exist or is corrupt. -133 * @throws DatabaseException when the database throws an exception. This usually occurs when the database is in use by another -134 * process. -135 */ -136 public void open() throws IOException, DatabaseException { -137 if (!isOpen()) { -138 cve = new CveDB(); -139 cve.open(); -140 cpe = CpeMemoryIndex.getInstance(); -141 try { -142 LOGGER.info("Creating the CPE Index"); -143 final long creationStart = System.currentTimeMillis(); -144 cpe.open(cve); -145 LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart); -146 } catch (IndexException ex) { -147 LOGGER.debug("IndexException", ex); -148 throw new DatabaseException(ex); -149 } -150 } -151 } -152 -153 /** -154 * Closes the data sources. -155 */ -156 @Override -157 public void close() { -158 if (cpe != null) { -159 cpe.close(); -160 cpe = null; -161 } -162 if (cve != null) { -163 cve.close(); -164 cve = null; -165 } -166 } -167 -168 public boolean isOpen() { -169 return cpe != null && cpe.isOpen(); -170 } -171 -172 /** -173 * Searches the data store of CPE entries, trying to identify the CPE for the given dependency based on the evidence contained -174 * within. The dependency passed in is updated with any identified CPE values. -175 * -176 * @param dependency the dependency to search for CPE entries on. -177 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. -178 * @throws IOException is thrown when an IOException occurs. -179 * @throws ParseException is thrown when the Lucene query cannot be parsed. -180 */ -181 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { -182 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit -183 String vendors = ""; -184 String products = ""; -185 for (Confidence confidence : Confidence.values()) { -186 if (dependency.getVendorEvidence().contains(confidence)) { -187 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); -188 LOGGER.debug("vendor search: {}", vendors); -189 } -190 if (dependency.getProductEvidence().contains(confidence)) { -191 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); -192 LOGGER.debug("product search: {}", products); -193 } -194 if (!vendors.isEmpty() && !products.isEmpty()) { -195 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(), -196 dependency.getVendorEvidence().getWeighting()); -197 if (entries == null) { -198 continue; -199 } -200 boolean identifierAdded = false; -201 for (IndexEntry e : entries) { -202 LOGGER.debug("Verifying entry: {}", e); -203 if (verifyEntry(e, dependency)) { -204 final String vendor = e.getVendor(); -205 final String product = e.getProduct(); -206 LOGGER.debug("identified vendor/product: {}/{}", vendor, product); -207 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); -208 } -209 } -210 if (identifierAdded) { -211 break; -212 } -213 } -214 } -215 } -216 -217 /** -218 * Returns the text created by concatenating the text and the values from the EvidenceCollection (filtered for a specific -219 * confidence). This attempts to prevent duplicate terms from being added.<br/<br/> Note, if the evidence is longer then 200 -220 * characters it will be truncated. -221 * -222 * @param text the base text. -223 * @param ec an EvidenceCollection -224 * @param confidenceFilter a Confidence level to filter the evidence by. -225 * @return the new evidence text -226 */ -227 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { -228 final String txt = (text == null) ? "" : text; -229 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); -230 sb.append(' ').append(txt).append(' '); -231 for (Evidence e : ec.iterator(confidenceFilter)) { -232 String value = e.getValue(); -233 -234 //hack to get around the fact that lucene does a really good job of recognizing domains and not -235 // splitting them. TODO - put together a better lucene analyzer specific to the domain. -236 if (value.startsWith("http://")) { -237 value = value.substring(7).replaceAll("\\.", " "); -238 } -239 if (value.startsWith("https://")) { -240 value = value.substring(8).replaceAll("\\.", " "); -241 } -242 if (sb.indexOf(" " + value + " ") < 0) { -243 sb.append(value).append(' '); -244 } -245 } -246 return sb.toString().trim(); -247 } -248 -249 /** -250 * <p> -251 * Searches the Lucene CPE index to identify possible CPE entries associated with the supplied vendor, product, and -252 * version.</p> -253 * -254 * <p> -255 * If either the vendorWeightings or productWeightings lists have been populated this data is used to add weighting factors to -256 * the search.</p> -257 * -258 * @param vendor the text used to search the vendor field -259 * @param product the text used to search the product field -260 * @param vendorWeightings a list of strings to use to add weighting factors to the vendor field -261 * @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search -262 * @return a list of possible CPE values -263 */ -264 protected List<IndexEntry> searchCPE(String vendor, String product, -265 Set<String> vendorWeightings, Set<String> productWeightings) { -266 -267 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); -268 -269 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); -270 if (searchString == null) { -271 return ret; -272 } -273 try { -274 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); -275 for (ScoreDoc d : docs.scoreDocs) { -276 if (d.score >= 0.08) { -277 final Document doc = cpe.getDocument(d.doc); -278 final IndexEntry entry = new IndexEntry(); -279 entry.setVendor(doc.get(Fields.VENDOR)); -280 entry.setProduct(doc.get(Fields.PRODUCT)); -281 entry.setSearchScore(d.score); -282 if (!ret.contains(entry)) { -283 ret.add(entry); -284 } -285 } -286 } -287 return ret; -288 } catch (ParseException ex) { -289 LOGGER.warn("An error occurred querying the CPE data. See the log for more details."); -290 LOGGER.info("Unable to parse: {}", searchString, ex); -291 } catch (IOException ex) { -292 LOGGER.warn("An error occurred reading CPE data. See the log for more details."); -293 LOGGER.info("IO Error with search string: {}", searchString, ex); -294 } -295 return null; -296 } -297 -298 /** -299 * <p> -300 * Builds a Lucene search string by properly escaping data and constructing a valid search query.</p> -301 * -302 * <p> -303 * If either the possibleVendor or possibleProducts lists have been populated this data is used to add weighting factors to -304 * the search string generated.</p> -305 * -306 * @param vendor text to search the vendor field -307 * @param product text to search the product field -308 * @param vendorWeighting a list of strings to apply to the vendor to boost the terms weight -309 * @param productWeightings a list of strings to apply to the product to boost the terms weight -310 * @return the Lucene query -311 */ -312 protected String buildSearch(String vendor, String product, -313 Set<String> vendorWeighting, Set<String> productWeightings) { -314 final String v = vendor; //.replaceAll("[^\\w\\d]", " "); -315 final String p = product; //.replaceAll("[^\\w\\d]", " "); -316 final StringBuilder sb = new StringBuilder(v.length() + p.length() -317 + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER); -318 -319 if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) { -320 return null; -321 } -322 sb.append(" AND "); -323 if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) { -324 return null; -325 } -326 return sb.toString(); -327 } -328 -329 /** -330 * This method constructs a Lucene query for a given field. The searchText is split into separate words and if the word is -331 * within the list of weighted words then an additional weighting is applied to the term as it is appended into the query. -332 * -333 * @param sb a StringBuilder that the query text will be appended to. -334 * @param field the field within the Lucene index that the query is searching. -335 * @param searchText text used to construct the query. -336 * @param weightedText a list of terms that will be considered higher importance when searching. -337 * @return if the append was successful. -338 */ -339 private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) { -340 sb.append(' ').append(field).append(":( "); +92 private CpeMemoryIndex cpe; +93 /** +94 * The CVE Database. +95 */ +96 private CveDB cve; +97 +98 /** +99 * The URL to perform a search of the NVD CVE data at NIST. +100 */ +101 public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s"; +102 +103 /** +104 * Returns the name of this analyzer. +105 * +106 * @return the name of this analyzer. +107 */ +108 @Override +109 public String getName() { +110 return "CPE Analyzer"; +111 } +112 +113 /** +114 * Returns the analysis phase that this analyzer should run in. +115 * +116 * @return the analysis phase that this analyzer should run in. +117 */ +118 @Override +119 public AnalysisPhase getAnalysisPhase() { +120 return AnalysisPhase.IDENTIFIER_ANALYSIS; +121 } +122 +123 /** +124 * Creates the CPE Lucene Index. +125 * +126 * @throws Exception is thrown if there is an issue opening the index. +127 */ +128 @Override +129 public void initialize() throws Exception { +130 this.open(); +131 } +132 +133 /** +134 * Opens the data source. +135 * +136 * @throws IOException when the Lucene directory to be queried does not +137 * exist or is corrupt. +138 * @throws DatabaseException when the database throws an exception. This +139 * usually occurs when the database is in use by another process. +140 */ +141 public void open() throws IOException, DatabaseException { +142 if (!isOpen()) { +143 cve = new CveDB(); +144 cve.open(); +145 cpe = CpeMemoryIndex.getInstance(); +146 try { +147 LOGGER.info("Creating the CPE Index"); +148 final long creationStart = System.currentTimeMillis(); +149 cpe.open(cve); +150 LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart); +151 } catch (IndexException ex) { +152 LOGGER.debug("IndexException", ex); +153 throw new DatabaseException(ex); +154 } +155 } +156 } +157 +158 /** +159 * Closes the data sources. +160 */ +161 @Override +162 public void close() { +163 if (cpe != null) { +164 cpe.close(); +165 cpe = null; +166 } +167 if (cve != null) { +168 cve.close(); +169 cve = null; +170 } +171 } +172 +173 public boolean isOpen() { +174 return cpe != null && cpe.isOpen(); +175 } +176 +177 /** +178 * Searches the data store of CPE entries, trying to identify the CPE for +179 * the given dependency based on the evidence contained within. The +180 * dependency passed in is updated with any identified CPE values. +181 * +182 * @param dependency the dependency to search for CPE entries on. +183 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. +184 * @throws IOException is thrown when an IOException occurs. +185 * @throws ParseException is thrown when the Lucene query cannot be parsed. +186 */ +187 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { +188 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit +189 String vendors = ""; +190 String products = ""; +191 for (Confidence confidence : Confidence.values()) { +192 if (dependency.getVendorEvidence().contains(confidence)) { +193 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); +194 LOGGER.debug("vendor search: {}", vendors); +195 } +196 if (dependency.getProductEvidence().contains(confidence)) { +197 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); +198 LOGGER.debug("product search: {}", products); +199 } +200 if (!vendors.isEmpty() && !products.isEmpty()) { +201 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(), +202 dependency.getProductEvidence().getWeighting()); +203 if (entries == null) { +204 continue; +205 } +206 boolean identifierAdded = false; +207 for (IndexEntry e : entries) { +208 LOGGER.debug("Verifying entry: {}", e); +209 if (verifyEntry(e, dependency)) { +210 final String vendor = e.getVendor(); +211 final String product = e.getProduct(); +212 LOGGER.debug("identified vendor/product: {}/{}", vendor, product); +213 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); +214 } +215 } +216 if (identifierAdded) { +217 break; +218 } +219 } +220 } +221 } +222 +223 /** +224 * Returns the text created by concatenating the text and the values from +225 * the EvidenceCollection (filtered for a specific confidence). This +226 * attempts to prevent duplicate terms from being added.<br/<br/> Note, if +227 * the evidence is longer then 200 characters it will be truncated. +228 * +229 * @param text the base text. +230 * @param ec an EvidenceCollection +231 * @param confidenceFilter a Confidence level to filter the evidence by. +232 * @return the new evidence text +233 */ +234 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { +235 final String txt = (text == null) ? "" : text; +236 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); +237 sb.append(' ').append(txt).append(' '); +238 for (Evidence e : ec.iterator(confidenceFilter)) { +239 String value = e.getValue(); +240 +241 //hack to get around the fact that lucene does a really good job of recognizing domains and not +242 // splitting them. TODO - put together a better lucene analyzer specific to the domain. +243 if (value.startsWith("http://")) { +244 value = value.substring(7).replaceAll("\\.", " "); +245 } +246 if (value.startsWith("https://")) { +247 value = value.substring(8).replaceAll("\\.", " "); +248 } +249 if (sb.indexOf(" " + value + " ") < 0) { +250 sb.append(value).append(' '); +251 } +252 } +253 return sb.toString().trim(); +254 } +255 +256 /** +257 * <p> +258 * Searches the Lucene CPE index to identify possible CPE entries associated +259 * with the supplied vendor, product, and version.</p> +260 * +261 * <p> +262 * If either the vendorWeightings or productWeightings lists have been +263 * populated this data is used to add weighting factors to the search.</p> +264 * +265 * @param vendor the text used to search the vendor field +266 * @param product the text used to search the product field +267 * @param vendorWeightings a list of strings to use to add weighting factors +268 * to the vendor field +269 * @param productWeightings Adds a list of strings that will be used to add +270 * weighting factors to the product search +271 * @return a list of possible CPE values +272 */ +273 protected List<IndexEntry> searchCPE(String vendor, String product, +274 Set<String> vendorWeightings, Set<String> productWeightings) { +275 +276 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); +277 +278 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); +279 if (searchString == null) { +280 return ret; +281 } +282 try { +283 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); +284 for (ScoreDoc d : docs.scoreDocs) { +285 if (d.score >= 0.08) { +286 final Document doc = cpe.getDocument(d.doc); +287 final IndexEntry entry = new IndexEntry(); +288 entry.setVendor(doc.get(Fields.VENDOR)); +289 entry.setProduct(doc.get(Fields.PRODUCT)); +290 entry.setSearchScore(d.score); +291 if (!ret.contains(entry)) { +292 ret.add(entry); +293 } +294 } +295 } +296 return ret; +297 } catch (ParseException ex) { +298 LOGGER.warn("An error occurred querying the CPE data. See the log for more details."); +299 LOGGER.info("Unable to parse: {}", searchString, ex); +300 } catch (IOException ex) { +301 LOGGER.warn("An error occurred reading CPE data. See the log for more details."); +302 LOGGER.info("IO Error with search string: {}", searchString, ex); +303 } +304 return null; +305 } +306 +307 /** +308 * <p> +309 * Builds a Lucene search string by properly escaping data and constructing +310 * a valid search query.</p> +311 * +312 * <p> +313 * If either the possibleVendor or possibleProducts lists have been +314 * populated this data is used to add weighting factors to the search string +315 * generated.</p> +316 * +317 * @param vendor text to search the vendor field +318 * @param product text to search the product field +319 * @param vendorWeighting a list of strings to apply to the vendor to boost +320 * the terms weight +321 * @param productWeightings a list of strings to apply to the product to +322 * boost the terms weight +323 * @return the Lucene query +324 */ +325 protected String buildSearch(String vendor, String product, +326 Set<String> vendorWeighting, Set<String> productWeightings) { +327 final String v = vendor; //.replaceAll("[^\\w\\d]", " "); +328 final String p = product; //.replaceAll("[^\\w\\d]", " "); +329 final StringBuilder sb = new StringBuilder(v.length() + p.length() +330 + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER); +331 +332 if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) { +333 return null; +334 } +335 sb.append(" AND "); +336 if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) { +337 return null; +338 } +339 return sb.toString(); +340 } 341 -342 final String cleanText = cleanseText(searchText); -343 -344 if (cleanText.isEmpty()) { -345 return false; -346 } -347 -348 if (weightedText == null || weightedText.isEmpty()) { -349 LuceneUtils.appendEscapedLuceneQuery(sb, cleanText); -350 } else { -351 final StringTokenizer tokens = new StringTokenizer(cleanText); -352 while (tokens.hasMoreElements()) { -353 final String word = tokens.nextToken(); -354 StringBuilder temp = null; -355 for (String weighted : weightedText) { -356 final String weightedStr = cleanseText(weighted); -357 if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) { -358 temp = new StringBuilder(word.length() + 2); -359 LuceneUtils.appendEscapedLuceneQuery(temp, word); -360 temp.append(WEIGHTING_BOOST); -361 if (!word.equalsIgnoreCase(weightedStr)) { -362 temp.append(' '); -363 LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr); -364 temp.append(WEIGHTING_BOOST); -365 } -366 break; -367 } -368 } -369 sb.append(' '); -370 if (temp == null) { -371 LuceneUtils.appendEscapedLuceneQuery(sb, word); -372 } else { -373 sb.append(temp); -374 } -375 } -376 } -377 sb.append(" ) "); -378 return true; -379 } -380 -381 /** -382 * Removes characters from the input text that are not used within the CPE index. -383 * -384 * @param text is the text to remove the characters from. -385 * @return the text having removed some characters. -386 */ -387 private String cleanseText(String text) { -388 return text.replaceAll(CLEANSE_CHARACTER_RX, " "); -389 } -390 -391 /** -392 * Compares two strings after lower casing them and removing the non-alpha characters. -393 * -394 * @param l string one to compare. -395 * @param r string two to compare. -396 * @return whether or not the two strings are similar. -397 */ -398 private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) { -399 if (l == null || r == null) { -400 return false; -401 } -402 -403 final String left = l.replaceAll(CLEANSE_NONALPHA_RX, ""); -404 final String right = r.replaceAll(CLEANSE_NONALPHA_RX, ""); -405 return left.equalsIgnoreCase(right); -406 } -407 -408 /** -409 * Ensures that the CPE Identified matches the dependency. This validates that the product, vendor, and version information -410 * for the CPE are contained within the dependencies evidence. -411 * -412 * @param entry a CPE entry. -413 * @param dependency the dependency that the CPE entries could be for. -414 * @return whether or not the entry is valid. -415 */ -416 private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) { -417 boolean isValid = false; -418 -419 //TODO - does this nullify some of the fuzzy matching that happens in the lucene search? -420 // for instance CPE some-component and in the evidence we have SomeComponent. -421 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) -422 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { -423 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) -424 isValid = true; -425 } -426 return isValid; -427 } -428 -429 /** -430 * Used to determine if the EvidenceCollection contains a specific string. +342 /** +343 * This method constructs a Lucene query for a given field. The searchText +344 * is split into separate words and if the word is within the list of +345 * weighted words then an additional weighting is applied to the term as it +346 * is appended into the query. +347 * +348 * @param sb a StringBuilder that the query text will be appended to. +349 * @param field the field within the Lucene index that the query is +350 * searching. +351 * @param searchText text used to construct the query. +352 * @param weightedText a list of terms that will be considered higher +353 * importance when searching. +354 * @return if the append was successful. +355 */ +356 private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) { +357 sb.append(' ').append(field).append(":( "); +358 +359 final String cleanText = cleanseText(searchText); +360 +361 if (cleanText.isEmpty()) { +362 return false; +363 } +364 +365 if (weightedText == null || weightedText.isEmpty()) { +366 LuceneUtils.appendEscapedLuceneQuery(sb, cleanText); +367 } else { +368 final StringTokenizer tokens = new StringTokenizer(cleanText); +369 while (tokens.hasMoreElements()) { +370 final String word = tokens.nextToken(); +371 StringBuilder temp = null; +372 for (String weighted : weightedText) { +373 final String weightedStr = cleanseText(weighted); +374 if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) { +375 temp = new StringBuilder(word.length() + 2); +376 LuceneUtils.appendEscapedLuceneQuery(temp, word); +377 temp.append(WEIGHTING_BOOST); +378 if (!word.equalsIgnoreCase(weightedStr)) { +379 temp.append(' '); +380 LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr); +381 temp.append(WEIGHTING_BOOST); +382 } +383 break; +384 } +385 } +386 sb.append(' '); +387 if (temp == null) { +388 LuceneUtils.appendEscapedLuceneQuery(sb, word); +389 } else { +390 sb.append(temp); +391 } +392 } +393 } +394 sb.append(" ) "); +395 return true; +396 } +397 +398 /** +399 * Removes characters from the input text that are not used within the CPE +400 * index. +401 * +402 * @param text is the text to remove the characters from. +403 * @return the text having removed some characters. +404 */ +405 private String cleanseText(String text) { +406 return text.replaceAll(CLEANSE_CHARACTER_RX, " "); +407 } +408 +409 /** +410 * Compares two strings after lower casing them and removing the non-alpha +411 * characters. +412 * +413 * @param l string one to compare. +414 * @param r string two to compare. +415 * @return whether or not the two strings are similar. +416 */ +417 private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) { +418 if (l == null || r == null) { +419 return false; +420 } +421 +422 final String left = l.replaceAll(CLEANSE_NONALPHA_RX, ""); +423 final String right = r.replaceAll(CLEANSE_NONALPHA_RX, ""); +424 return left.equalsIgnoreCase(right); +425 } +426 +427 /** +428 * Ensures that the CPE Identified matches the dependency. This validates +429 * that the product, vendor, and version information for the CPE are +430 * contained within the dependencies evidence. 431 * -432 * @param ec an EvidenceCollection -433 * @param text the text to search for -434 * @return whether or not the EvidenceCollection contains the string +432 * @param entry a CPE entry. +433 * @param dependency the dependency that the CPE entries could be for. +434 * @return whether or not the entry is valid. 435 */ -436 private boolean collectionContainsString(EvidenceCollection ec, String text) { -437 //TODO - likely need to change the split... not sure if this will work for CPE with special chars -438 if (text == null) { -439 return false; -440 } -441 final String[] words = text.split("[\\s_-]"); -442 final List<String> list = new ArrayList<String>(); -443 String tempWord = null; -444 for (String word : words) { -445 /* -446 single letter words should be concatenated with the next word. -447 so { "m", "core", "sample" } -> { "mcore", "sample" } -448 */ -449 if (tempWord != null) { -450 list.add(tempWord + word); -451 tempWord = null; -452 } else if (word.length() <= 2) { -453 tempWord = word; -454 } else { -455 list.add(word); -456 } -457 } -458 if (tempWord != null) { -459 if (!list.isEmpty()) { -460 final String tmp = list.get(list.size() - 1) + tempWord; -461 list.add(tmp); -462 } else { -463 list.add(tempWord); -464 } -465 } -466 if (list.isEmpty()) { -467 return false; -468 } -469 boolean contains = true; -470 for (String word : list) { -471 contains &= ec.containsUsedString(word); -472 } -473 return contains; -474 } -475 -476 /** -477 * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency. -478 * -479 * @param dependency The Dependency to analyze. -480 * @param engine The analysis engine -481 * @throws AnalysisException is thrown if there is an issue analyzing the dependency. -482 */ -483 @Override -484 public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException { -485 try { -486 determineCPE(dependency); -487 } catch (CorruptIndexException ex) { -488 throw new AnalysisException("CPE Index is corrupt.", ex); -489 } catch (IOException ex) { -490 throw new AnalysisException("Failure opening the CPE Index.", ex); -491 } catch (ParseException ex) { -492 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); -493 } +436 private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) { +437 boolean isValid = false; +438 +439 //TODO - does this nullify some of the fuzzy matching that happens in the lucene search? +440 // for instance CPE some-component and in the evidence we have SomeComponent. +441 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) +442 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { +443 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) +444 isValid = true; +445 } +446 return isValid; +447 } +448 +449 /** +450 * Used to determine if the EvidenceCollection contains a specific string. +451 * +452 * @param ec an EvidenceCollection +453 * @param text the text to search for +454 * @return whether or not the EvidenceCollection contains the string +455 */ +456 private boolean collectionContainsString(EvidenceCollection ec, String text) { +457 //TODO - likely need to change the split... not sure if this will work for CPE with special chars +458 if (text == null) { +459 return false; +460 } +461 final String[] words = text.split("[\\s_-]"); +462 final List<String> list = new ArrayList<String>(); +463 String tempWord = null; +464 for (String word : words) { +465 /* +466 single letter words should be concatenated with the next word. +467 so { "m", "core", "sample" } -> { "mcore", "sample" } +468 */ +469 if (tempWord != null) { +470 list.add(tempWord + word); +471 tempWord = null; +472 } else if (word.length() <= 2) { +473 tempWord = word; +474 } else { +475 list.add(word); +476 } +477 } +478 if (tempWord != null) { +479 if (!list.isEmpty()) { +480 final String tmp = list.get(list.size() - 1) + tempWord; +481 list.add(tmp); +482 } else { +483 list.add(tempWord); +484 } +485 } +486 if (list.isEmpty()) { +487 return false; +488 } +489 boolean contains = true; +490 for (String word : list) { +491 contains &= ec.containsUsedString(word); +492 } +493 return contains; 494 } 495 496 /** -497 * Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then validated to find -498 * only CPEs that are valid for the given dependency. It is possible that the CPE identified is a best effort "guess" based on -499 * the vendor, product, and version information. -500 * -501 * @param dependency the Dependency being analyzed -502 * @param vendor the vendor for the CPE being analyzed -503 * @param product the product for the CPE being analyzed -504 * @param currentConfidence the current confidence being used during analysis -505 * @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code> -506 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported -507 */ -508 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, -509 Confidence currentConfidence) throws UnsupportedEncodingException { -510 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); -511 DependencyVersion bestGuess = new DependencyVersion("-"); -512 Confidence bestGuessConf = null; -513 boolean hasBroadMatch = false; -514 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); -515 for (Confidence conf : Confidence.values()) { -516 // if (conf.compareTo(currentConfidence) > 0) { -517 // break; -518 // } -519 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { -520 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); -521 if (evVer == null) { -522 continue; -523 } -524 for (VulnerableSoftware vs : cpes) { -525 DependencyVersion dbVer; -526 if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) { -527 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate()); -528 } else { -529 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); -530 } -531 if (dbVer == null) { //special case, no version specified - everything is vulnerable -532 hasBroadMatch = true; -533 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -534 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); -535 collected.add(match); -536 } else if (evVer.equals(dbVer)) { //yeah! exact match -537 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -538 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); -539 collected.add(match); -540 } else { -541 //TODO the following isn't quite right is it? need to think about this guessing game a bit more. -542 if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() -543 && evVer.matchesAtLeastThreeLevels(dbVer)) { -544 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -545 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { -546 bestGuess = dbVer; -547 bestGuessConf = conf; -548 } -549 } -550 } -551 } -552 } -553 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -554 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { -555 bestGuess = evVer; -556 bestGuessConf = conf; +497 * Analyzes a dependency and attempts to determine if there are any CPE +498 * identifiers for this dependency. +499 * +500 * @param dependency The Dependency to analyze. +501 * @param engine The analysis engine +502 * @throws AnalysisException is thrown if there is an issue analyzing the +503 * dependency. +504 */ +505 @Override +506 public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException { +507 try { +508 determineCPE(dependency); +509 } catch (CorruptIndexException ex) { +510 throw new AnalysisException("CPE Index is corrupt.", ex); +511 } catch (IOException ex) { +512 throw new AnalysisException("Failure opening the CPE Index.", ex); +513 } catch (ParseException ex) { +514 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); +515 } +516 } +517 +518 /** +519 * Retrieves a list of CPE values from the CveDB based on the vendor and +520 * product passed in. The list is then validated to find only CPEs that are +521 * valid for the given dependency. It is possible that the CPE identified is +522 * a best effort "guess" based on the vendor, product, and version +523 * information. +524 * +525 * @param dependency the Dependency being analyzed +526 * @param vendor the vendor for the CPE being analyzed +527 * @param product the product for the CPE being analyzed +528 * @param currentConfidence the current confidence being used during +529 * analysis +530 * @return <code>true</code> if an identifier was added to the dependency; +531 * otherwise <code>false</code> +532 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported +533 */ +534 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, +535 Confidence currentConfidence) throws UnsupportedEncodingException { +536 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); +537 DependencyVersion bestGuess = new DependencyVersion("-"); +538 Confidence bestGuessConf = null; +539 boolean hasBroadMatch = false; +540 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); +541 +542 //TODO the following algorithm incorrectly identifies things as a lower version +543 // if there lower confidence evidence when the current (highest) version number +544 // is newer then anything in the NVD. +545 for (Confidence conf : Confidence.values()) { +546 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { +547 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); +548 if (evVer == null) { +549 continue; +550 } +551 for (VulnerableSoftware vs : cpes) { +552 DependencyVersion dbVer; +553 if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) { +554 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate()); +555 } else { +556 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); 557 } -558 } -559 } -560 } -561 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); -562 String url = null; -563 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. -564 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); -565 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); -566 } -567 if (bestGuessConf == null) { -568 bestGuessConf = Confidence.LOW; -569 } -570 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); -571 collected.add(match); -572 -573 Collections.sort(collected); -574 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); -575 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); -576 boolean identifierAdded = false; -577 for (IdentifierMatch m : collected) { -578 if (bestIdentifierQuality.equals(m.getConfidence()) -579 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { -580 final Identifier i = m.getIdentifier(); -581 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { -582 i.setConfidence(Confidence.LOW); -583 } else { -584 i.setConfidence(bestEvidenceQuality); -585 } -586 dependency.addIdentifier(i); -587 identifierAdded = true; -588 } -589 } -590 return identifierAdded; -591 } -592 -593 /** -594 * The confidence whether the identifier is an exact match, or a best guess. -595 */ -596 private enum IdentifierConfidence { +558 if (dbVer == null) { //special case, no version specified - everything is vulnerable +559 hasBroadMatch = true; +560 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +561 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); +562 collected.add(match); +563 } else if (evVer.equals(dbVer)) { //yeah! exact match +564 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +565 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); +566 collected.add(match); +567 } else //TODO the following isn't quite right is it? need to think about this guessing game a bit more. +568 if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() +569 && evVer.matchesAtLeastThreeLevels(dbVer)) { +570 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +571 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { +572 bestGuess = dbVer; +573 bestGuessConf = conf; +574 } +575 } +576 } +577 } +578 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +579 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { +580 bestGuess = evVer; +581 bestGuessConf = conf; +582 } +583 } +584 } +585 } +586 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); +587 String url = null; +588 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. +589 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); +590 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); +591 } +592 if (bestGuessConf == null) { +593 bestGuessConf = Confidence.LOW; +594 } +595 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); +596 collected.add(match); 597 -598 /** -599 * An exact match for the CPE. -600 */ -601 EXACT_MATCH, -602 /** -603 * A best guess for the CPE. -604 */ -605 BEST_GUESS, -606 /** -607 * The entire vendor/product group must be added (without a guess at version) because there is a CVE with a VS that only -608 * specifies vendor/product. -609 */ -610 BROAD_MATCH -611 } -612 -613 /** -614 * A simple object to hold an identifier and carry information about the confidence in the identifier. -615 */ -616 private static class IdentifierMatch implements Comparable<IdentifierMatch> { +598 Collections.sort(collected); +599 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); +600 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); +601 boolean identifierAdded = false; +602 for (IdentifierMatch m : collected) { +603 if (bestIdentifierQuality.equals(m.getConfidence()) +604 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { +605 final Identifier i = m.getIdentifier(); +606 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { +607 i.setConfidence(Confidence.LOW); +608 } else { +609 i.setConfidence(bestEvidenceQuality); +610 } +611 dependency.addIdentifier(i); +612 identifierAdded = true; +613 } +614 } +615 return identifierAdded; +616 } 617 -618 /** -619 * Constructs an IdentifierMatch. -620 * -621 * @param type the type of identifier (such as CPE) -622 * @param value the value of the identifier -623 * @param url the URL of the identifier -624 * @param identifierConfidence the confidence in the identifier: best guess or exact match -625 * @param evidenceConfidence the confidence of the evidence used to find the identifier -626 */ -627 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { -628 this.identifier = new Identifier(type, value, url); -629 this.confidence = identifierConfidence; -630 this.evidenceConfidence = evidenceConfidence; -631 } -632 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> -633 /** -634 * The confidence in the evidence used to identify this match. +618 /** +619 * The confidence whether the identifier is an exact match, or a best guess. +620 */ +621 private enum IdentifierConfidence { +622 +623 /** +624 * An exact match for the CPE. +625 */ +626 EXACT_MATCH, +627 /** +628 * A best guess for the CPE. +629 */ +630 BEST_GUESS, +631 /** +632 * The entire vendor/product group must be added (without a guess at +633 * version) because there is a CVE with a VS that only specifies +634 * vendor/product. 635 */ -636 private Confidence evidenceConfidence; -637 -638 /** -639 * Get the value of evidenceConfidence -640 * -641 * @return the value of evidenceConfidence -642 */ -643 public Confidence getEvidenceConfidence() { -644 return evidenceConfidence; -645 } -646 -647 /** -648 * Set the value of evidenceConfidence -649 * -650 * @param evidenceConfidence new value of evidenceConfidence -651 */ -652 public void setEvidenceConfidence(Confidence evidenceConfidence) { -653 this.evidenceConfidence = evidenceConfidence; -654 } -655 /** -656 * The confidence whether this is an exact match, or a best guess. -657 */ -658 private IdentifierConfidence confidence; -659 -660 /** -661 * Get the value of confidence. -662 * -663 * @return the value of confidence +636 BROAD_MATCH +637 } +638 +639 /** +640 * A simple object to hold an identifier and carry information about the +641 * confidence in the identifier. +642 */ +643 private static class IdentifierMatch implements Comparable<IdentifierMatch> { +644 +645 /** +646 * Constructs an IdentifierMatch. +647 * +648 * @param type the type of identifier (such as CPE) +649 * @param value the value of the identifier +650 * @param url the URL of the identifier +651 * @param identifierConfidence the confidence in the identifier: best +652 * guess or exact match +653 * @param evidenceConfidence the confidence of the evidence used to find +654 * the identifier +655 */ +656 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { +657 this.identifier = new Identifier(type, value, url); +658 this.confidence = identifierConfidence; +659 this.evidenceConfidence = evidenceConfidence; +660 } +661 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> +662 /** +663 * The confidence in the evidence used to identify this match. 664 */ -665 public IdentifierConfidence getConfidence() { -666 return confidence; -667 } -668 -669 /** -670 * Set the value of confidence. -671 * -672 * @param confidence new value of confidence -673 */ -674 public void setConfidence(IdentifierConfidence confidence) { -675 this.confidence = confidence; -676 } -677 /** -678 * The CPE identifier. -679 */ -680 private Identifier identifier; -681 -682 /** -683 * Get the value of identifier. -684 * -685 * @return the value of identifier +665 private Confidence evidenceConfidence; +666 +667 /** +668 * Get the value of evidenceConfidence +669 * +670 * @return the value of evidenceConfidence +671 */ +672 public Confidence getEvidenceConfidence() { +673 return evidenceConfidence; +674 } +675 +676 /** +677 * Set the value of evidenceConfidence +678 * +679 * @param evidenceConfidence new value of evidenceConfidence +680 */ +681 public void setEvidenceConfidence(Confidence evidenceConfidence) { +682 this.evidenceConfidence = evidenceConfidence; +683 } +684 /** +685 * The confidence whether this is an exact match, or a best guess. 686 */ -687 public Identifier getIdentifier() { -688 return identifier; -689 } -690 -691 /** -692 * Set the value of identifier. -693 * -694 * @param identifier new value of identifier -695 */ -696 public void setIdentifier(Identifier identifier) { -697 this.identifier = identifier; -698 } -699 //</editor-fold> -700 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> -701 -702 /** -703 * Standard toString() implementation. -704 * -705 * @return the string representation of the object -706 */ -707 @Override -708 public String toString() { -709 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence -710 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; -711 } -712 -713 /** -714 * Standard hashCode() implementation. -715 * -716 * @return the hashCode -717 */ -718 @Override -719 public int hashCode() { -720 int hash = 5; -721 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); -722 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); -723 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); -724 return hash; -725 } -726 -727 /** -728 * Standard equals implementation. -729 * -730 * @param obj the object to compare -731 * @return true if the objects are equal, otherwise false -732 */ -733 @Override -734 public boolean equals(Object obj) { -735 if (obj == null) { -736 return false; -737 } -738 if (getClass() != obj.getClass()) { -739 return false; -740 } -741 final IdentifierMatch other = (IdentifierMatch) obj; -742 if (this.evidenceConfidence != other.evidenceConfidence) { -743 return false; -744 } -745 if (this.confidence != other.confidence) { -746 return false; -747 } -748 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { -749 return false; -750 } -751 return true; -752 } -753 //</editor-fold> -754 -755 /** -756 * Standard implementation of compareTo that compares identifier confidence, evidence confidence, and then the identifier. -757 * -758 * @param o the IdentifierMatch to compare to -759 * @return the natural ordering of IdentifierMatch -760 */ -761 @Override -762 public int compareTo(IdentifierMatch o) { -763 int conf = this.confidence.compareTo(o.confidence); -764 if (conf == 0) { -765 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); -766 if (conf == 0) { -767 conf = identifier.compareTo(o.identifier); -768 } +687 private IdentifierConfidence confidence; +688 +689 /** +690 * Get the value of confidence. +691 * +692 * @return the value of confidence +693 */ +694 public IdentifierConfidence getConfidence() { +695 return confidence; +696 } +697 +698 /** +699 * Set the value of confidence. +700 * +701 * @param confidence new value of confidence +702 */ +703 public void setConfidence(IdentifierConfidence confidence) { +704 this.confidence = confidence; +705 } +706 /** +707 * The CPE identifier. +708 */ +709 private Identifier identifier; +710 +711 /** +712 * Get the value of identifier. +713 * +714 * @return the value of identifier +715 */ +716 public Identifier getIdentifier() { +717 return identifier; +718 } +719 +720 /** +721 * Set the value of identifier. +722 * +723 * @param identifier new value of identifier +724 */ +725 public void setIdentifier(Identifier identifier) { +726 this.identifier = identifier; +727 } +728 //</editor-fold> +729 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> +730 +731 /** +732 * Standard toString() implementation. +733 * +734 * @return the string representation of the object +735 */ +736 @Override +737 public String toString() { +738 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence +739 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; +740 } +741 +742 /** +743 * Standard hashCode() implementation. +744 * +745 * @return the hashCode +746 */ +747 @Override +748 public int hashCode() { +749 int hash = 5; +750 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); +751 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); +752 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); +753 return hash; +754 } +755 +756 /** +757 * Standard equals implementation. +758 * +759 * @param obj the object to compare +760 * @return true if the objects are equal, otherwise false +761 */ +762 @Override +763 public boolean equals(Object obj) { +764 if (obj == null) { +765 return false; +766 } +767 if (getClass() != obj.getClass()) { +768 return false; 769 } -770 return conf; -771 } -772 } -773 } +770 final IdentifierMatch other = (IdentifierMatch) obj; +771 if (this.evidenceConfidence != other.evidenceConfidence) { +772 return false; +773 } +774 if (this.confidence != other.confidence) { +775 return false; +776 } +777 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { +778 return false; +779 } +780 return true; +781 } +782 //</editor-fold> +783 +784 /** +785 * Standard implementation of compareTo that compares identifier +786 * confidence, evidence confidence, and then the identifier. +787 * +788 * @param o the IdentifierMatch to compare to +789 * @return the natural ordering of IdentifierMatch +790 */ +791 @Override +792 public int compareTo(IdentifierMatch o) { +793 int conf = this.confidence.compareTo(o.confidence); +794 if (conf == 0) { +795 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); +796 if (conf == 0) { +797 conf = identifier.compareTo(o.identifier); +798 } +799 } +800 return conf; +801 } +802 } +803 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html index 6dc735f81..81b4a7155 100644 --- a/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html @@ -49,125 +49,126 @@ 41 * 42 * @author colezlaw 43 */ -44 public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { -45 -46 /** -47 * The logger. -48 */ -49 private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class); -50 -51 /** -52 * The analyzer name. -53 */ -54 private static final String ANALYZER_NAME = "Composer.lock analyzer"; -55 -56 /** -57 * composer.json. -58 */ -59 private static final String COMPOSER_LOCK = "composer.lock"; -60 -61 /** -62 * The FileFilter. -63 */ -64 private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build(); -65 -66 /** -67 * Returns the FileFilter. -68 * -69 * @return the FileFilter -70 */ -71 @Override -72 protected FileFilter getFileFilter() { -73 return FILE_FILTER; -74 } -75 -76 /** -77 * Initializes the analyzer. -78 * -79 * @throws Exception thrown if an exception occurs getting an instance of SHA1 -80 */ -81 @Override -82 protected void initializeFileTypeAnalyzer() throws Exception { -83 sha1 = MessageDigest.getInstance("SHA1"); -84 } -85 -86 /** -87 * The MessageDigest for calculating a new digest for the new dependencies added. -88 */ -89 private MessageDigest sha1 = null; -90 -91 /** -92 * Entry point for the analyzer. -93 * -94 * @param dependency the dependency to analyze -95 * @param engine the engine scanning -96 * @throws AnalysisException if there's a failure during analysis -97 */ -98 @Override -99 protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -100 FileInputStream fis = null; -101 try { -102 fis = new FileInputStream(dependency.getActualFile()); -103 final ComposerLockParser clp = new ComposerLockParser(fis); -104 LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath()); -105 clp.process(); -106 for (ComposerDependency dep : clp.getDependencies()) { -107 final Dependency d = new Dependency(dependency.getActualFile()); -108 d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject())); -109 final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject()); -110 d.setFilePath(filePath); -111 d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset())))); -112 d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST); -113 d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST); -114 d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST); -115 LOGGER.info("Adding dependency {}", d); -116 engine.getDependencies().add(d); -117 } -118 } catch (FileNotFoundException fnfe) { -119 LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath()); -120 } catch (ComposerException ce) { -121 LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce); -122 } finally { -123 if (fis != null) { -124 try { -125 fis.close(); -126 } catch (Exception e) { -127 LOGGER.debug("Unable to close file", e); -128 } -129 } -130 } -131 } -132 -133 /** -134 * Gets the key to determine whether the analyzer is enabled. -135 * -136 * @return the key specifying whether the analyzer is enabled -137 */ -138 @Override -139 protected String getAnalyzerEnabledSettingKey() { -140 return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED; -141 } -142 -143 /** -144 * Returns the analyzer's name. -145 * -146 * @return the analyzer's name -147 */ -148 @Override -149 public String getName() { -150 return ANALYZER_NAME; -151 } -152 -153 /** -154 * Returns the phase this analyzer should run under. -155 * -156 * @return the analysis phase -157 */ -158 @Override -159 public AnalysisPhase getAnalysisPhase() { -160 return AnalysisPhase.INFORMATION_COLLECTION; -161 } -162 } +44 @Experimental +45 public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { +46 +47 /** +48 * The logger. +49 */ +50 private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class); +51 +52 /** +53 * The analyzer name. +54 */ +55 private static final String ANALYZER_NAME = "Composer.lock analyzer"; +56 +57 /** +58 * composer.json. +59 */ +60 private static final String COMPOSER_LOCK = "composer.lock"; +61 +62 /** +63 * The FileFilter. +64 */ +65 private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build(); +66 +67 /** +68 * Returns the FileFilter. +69 * +70 * @return the FileFilter +71 */ +72 @Override +73 protected FileFilter getFileFilter() { +74 return FILE_FILTER; +75 } +76 +77 /** +78 * Initializes the analyzer. +79 * +80 * @throws Exception thrown if an exception occurs getting an instance of SHA1 +81 */ +82 @Override +83 protected void initializeFileTypeAnalyzer() throws Exception { +84 sha1 = MessageDigest.getInstance("SHA1"); +85 } +86 +87 /** +88 * The MessageDigest for calculating a new digest for the new dependencies added. +89 */ +90 private MessageDigest sha1 = null; +91 +92 /** +93 * Entry point for the analyzer. +94 * +95 * @param dependency the dependency to analyze +96 * @param engine the engine scanning +97 * @throws AnalysisException if there's a failure during analysis +98 */ +99 @Override +100 protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +101 FileInputStream fis = null; +102 try { +103 fis = new FileInputStream(dependency.getActualFile()); +104 final ComposerLockParser clp = new ComposerLockParser(fis); +105 LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath()); +106 clp.process(); +107 for (ComposerDependency dep : clp.getDependencies()) { +108 final Dependency d = new Dependency(dependency.getActualFile()); +109 d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject())); +110 final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject()); +111 d.setFilePath(filePath); +112 d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset())))); +113 d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST); +114 d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST); +115 d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST); +116 LOGGER.info("Adding dependency {}", d); +117 engine.getDependencies().add(d); +118 } +119 } catch (FileNotFoundException fnfe) { +120 LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath()); +121 } catch (ComposerException ce) { +122 LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce); +123 } finally { +124 if (fis != null) { +125 try { +126 fis.close(); +127 } catch (Exception e) { +128 LOGGER.debug("Unable to close file", e); +129 } +130 } +131 } +132 } +133 +134 /** +135 * Gets the key to determine whether the analyzer is enabled. +136 * +137 * @return the key specifying whether the analyzer is enabled +138 */ +139 @Override +140 protected String getAnalyzerEnabledSettingKey() { +141 return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED; +142 } +143 +144 /** +145 * Returns the analyzer's name. +146 * +147 * @return the analyzer's name +148 */ +149 @Override +150 public String getName() { +151 return ANALYZER_NAME; +152 } +153 +154 /** +155 * Returns the phase this analyzer should run under. +156 * +157 * @return the analysis phase +158 */ +159 @Override +160 public AnalysisPhase getAnalysisPhase() { +161 return AnalysisPhase.INFORMATION_COLLECTION; +162 } +163 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html index b822a93c1..b8b973dd7 100644 --- a/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html @@ -43,397 +43,475 @@ 35 36 /** 37 * <p> -38 * This analyzer ensures dependencies that should be grouped together, to remove excess noise from the report, are grouped. An -39 * example would be Spring, Spring Beans, Spring MVC, etc. If they are all for the same version and have the same relative path -40 * then these should be grouped into a single dependency under the core/main library.</p> -41 * <p> -42 * Note, this grouping only works on dependencies with identified CVE entries</p> -43 * -44 * @author Jeremy Long -45 */ -46 public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer { -47 -48 /** -49 * The Logger. -50 */ -51 private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class); -52 -53 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> -54 /** -55 * A pattern for obtaining the first part of a filename. -56 */ -57 private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*"); -58 /** -59 * a flag indicating if this analyzer has run. This analyzer only runs once. -60 */ -61 private boolean analyzed = false; -62 //</editor-fold> -63 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -64 /** -65 * The name of the analyzer. -66 */ -67 private static final String ANALYZER_NAME = "Dependency Bundling Analyzer"; -68 /** -69 * The phase that this analyzer is intended to run in. -70 */ -71 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS; -72 -73 /** -74 * Returns the name of the analyzer. -75 * -76 * @return the name of the analyzer. -77 */ -78 @Override -79 public String getName() { -80 return ANALYZER_NAME; -81 } -82 -83 /** -84 * Returns the phase that the analyzer is intended to run in. -85 * -86 * @return the phase that the analyzer is intended to run in. -87 */ -88 @Override -89 public AnalysisPhase getAnalysisPhase() { -90 return ANALYSIS_PHASE; -91 } -92 //</editor-fold> -93 -94 /** -95 * Analyzes a set of dependencies. If they have been found to have the same base path and the same set of identifiers they are -96 * likely related. The related dependencies are bundled into a single reportable item. -97 * -98 * @param ignore this analyzer ignores the dependency being analyzed -99 * @param engine the engine that is scanning the dependencies -100 * @throws AnalysisException is thrown if there is an error reading the JAR file. -101 */ -102 @Override -103 public void analyze(Dependency ignore, Engine engine) throws AnalysisException { -104 if (!analyzed) { -105 analyzed = true; -106 final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>(); -107 final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator(); -108 //for (Dependency nextDependency : engine.getDependencies()) { -109 while (mainIterator.hasNext()) { -110 final Dependency dependency = mainIterator.next(); -111 if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) { -112 final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex()); -113 while (subIterator.hasNext()) { -114 final Dependency nextDependency = subIterator.next(); -115 if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath()) -116 && !containedInWar(nextDependency.getFilePath())) { -117 if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) { -118 mergeDependencies(dependency, nextDependency, dependenciesToRemove); -119 } else { -120 mergeDependencies(nextDependency, dependency, dependenciesToRemove); -121 break; //since we merged into the next dependency - skip forward to the next in mainIterator -122 } -123 } else if (isShadedJar(dependency, nextDependency)) { -124 if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) { +38 * This analyzer ensures dependencies that should be grouped together, to remove +39 * excess noise from the report, are grouped. An example would be Spring, Spring +40 * Beans, Spring MVC, etc. If they are all for the same version and have the +41 * same relative path then these should be grouped into a single dependency +42 * under the core/main library.</p> +43 * <p> +44 * Note, this grouping only works on dependencies with identified CVE +45 * entries</p> +46 * +47 * @author Jeremy Long +48 */ +49 public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer { +50 +51 /** +52 * The Logger. +53 */ +54 private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class); +55 +56 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> +57 /** +58 * A pattern for obtaining the first part of a filename. +59 */ +60 private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*"); +61 /** +62 * a flag indicating if this analyzer has run. This analyzer only runs once. +63 */ +64 private boolean analyzed = false; +65 //</editor-fold> +66 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +67 /** +68 * The name of the analyzer. +69 */ +70 private static final String ANALYZER_NAME = "Dependency Bundling Analyzer"; +71 /** +72 * The phase that this analyzer is intended to run in. +73 */ +74 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS; +75 +76 /** +77 * Returns the name of the analyzer. +78 * +79 * @return the name of the analyzer. +80 */ +81 @Override +82 public String getName() { +83 return ANALYZER_NAME; +84 } +85 +86 /** +87 * Returns the phase that the analyzer is intended to run in. +88 * +89 * @return the phase that the analyzer is intended to run in. +90 */ +91 @Override +92 public AnalysisPhase getAnalysisPhase() { +93 return ANALYSIS_PHASE; +94 } +95 //</editor-fold> +96 +97 /** +98 * Analyzes a set of dependencies. If they have been found to have the same +99 * base path and the same set of identifiers they are likely related. The +100 * related dependencies are bundled into a single reportable item. +101 * +102 * @param ignore this analyzer ignores the dependency being analyzed +103 * @param engine the engine that is scanning the dependencies +104 * @throws AnalysisException is thrown if there is an error reading the JAR +105 * file. +106 */ +107 @Override +108 public void analyze(Dependency ignore, Engine engine) throws AnalysisException { +109 if (!analyzed) { +110 analyzed = true; +111 final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>(); +112 final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator(); +113 //for (Dependency nextDependency : engine.getDependencies()) { +114 while (mainIterator.hasNext()) { +115 final Dependency dependency = mainIterator.next(); +116 if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) { +117 final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex()); +118 while (subIterator.hasNext()) { +119 final Dependency nextDependency = subIterator.next(); +120 if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath()) +121 && !containedInWar(nextDependency.getFilePath())) { +122 if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) { +123 mergeDependencies(dependency, nextDependency, dependenciesToRemove); +124 } else { 125 mergeDependencies(nextDependency, dependency, dependenciesToRemove); -126 nextDependency.getRelatedDependencies().remove(dependency); -127 break; -128 } else { -129 mergeDependencies(dependency, nextDependency, dependenciesToRemove); -130 dependency.getRelatedDependencies().remove(nextDependency); -131 } -132 } else if (cpeIdentifiersMatch(dependency, nextDependency) -133 && hasSameBasePath(dependency, nextDependency) -134 && fileNameMatch(dependency, nextDependency)) { -135 if (isCore(dependency, nextDependency)) { -136 mergeDependencies(dependency, nextDependency, dependenciesToRemove); -137 } else { -138 mergeDependencies(nextDependency, dependency, dependenciesToRemove); -139 break; //since we merged into the next dependency - skip forward to the next in mainIterator -140 } -141 } -142 } -143 } -144 } -145 //removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions -146 // was difficult because of the inner iterator. -147 engine.getDependencies().removeAll(dependenciesToRemove); -148 } -149 } -150 -151 /** -152 * Adds the relatedDependency to the dependency's related dependencies. -153 * -154 * @param dependency the main dependency -155 * @param relatedDependency a collection of dependencies to be removed from the main analysis loop, this is the source of -156 * dependencies to remove -157 * @param dependenciesToRemove a collection of dependencies that will be removed from the main analysis loop, this function -158 * adds to this collection -159 */ -160 private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) { -161 dependency.addRelatedDependency(relatedDependency); -162 final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator(); -163 while (i.hasNext()) { -164 dependency.addRelatedDependency(i.next()); -165 i.remove(); -166 } -167 if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) { -168 dependency.addAllProjectReferences(relatedDependency.getProjectReferences()); -169 } -170 dependenciesToRemove.add(relatedDependency); -171 } -172 -173 /** -174 * Attempts to trim a maven repo to a common base path. This is typically [drive]\[repo_location]\repository\[path1]\[path2]. -175 * -176 * @param path the path to trim -177 * @return a string representing the base path. -178 */ -179 private String getBaseRepoPath(final String path) { -180 int pos = path.indexOf("repository" + File.separator) + 11; -181 if (pos < 0) { -182 return path; +126 break; //since we merged into the next dependency - skip forward to the next in mainIterator +127 } +128 } else if (isShadedJar(dependency, nextDependency)) { +129 if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) { +130 mergeDependencies(nextDependency, dependency, dependenciesToRemove); +131 nextDependency.getRelatedDependencies().remove(dependency); +132 break; +133 } else { +134 mergeDependencies(dependency, nextDependency, dependenciesToRemove); +135 dependency.getRelatedDependencies().remove(nextDependency); +136 } +137 } else if (cpeIdentifiersMatch(dependency, nextDependency) +138 && hasSameBasePath(dependency, nextDependency) +139 && fileNameMatch(dependency, nextDependency)) { +140 if (isCore(dependency, nextDependency)) { +141 mergeDependencies(dependency, nextDependency, dependenciesToRemove); +142 } else { +143 mergeDependencies(nextDependency, dependency, dependenciesToRemove); +144 break; //since we merged into the next dependency - skip forward to the next in mainIterator +145 } +146 } else if (isSameRubyGem(dependency, nextDependency)) { +147 final Dependency main = getMainGemspecDependency(dependency, nextDependency); +148 if (main == dependency) { +149 mergeDependencies(dependency, nextDependency, dependenciesToRemove); +150 } else { +151 mergeDependencies(nextDependency, dependency, dependenciesToRemove); +152 break; //since we merged into the next dependency - skip forward to the next in mainIterator +153 } +154 } +155 } +156 } +157 } +158 //removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions +159 // was difficult because of the inner iterator. +160 engine.getDependencies().removeAll(dependenciesToRemove); +161 } +162 } +163 +164 /** +165 * Adds the relatedDependency to the dependency's related dependencies. +166 * +167 * @param dependency the main dependency +168 * @param relatedDependency a collection of dependencies to be removed from +169 * the main analysis loop, this is the source of dependencies to remove +170 * @param dependenciesToRemove a collection of dependencies that will be +171 * removed from the main analysis loop, this function adds to this +172 * collection +173 */ +174 private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) { +175 dependency.addRelatedDependency(relatedDependency); +176 final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator(); +177 while (i.hasNext()) { +178 dependency.addRelatedDependency(i.next()); +179 i.remove(); +180 } +181 if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) { +182 dependency.addAllProjectReferences(relatedDependency.getProjectReferences()); 183 } -184 int tmp = path.indexOf(File.separator, pos); -185 if (tmp <= 0) { -186 return path; -187 } -188 if (tmp > 0) { -189 pos = tmp + 1; -190 } -191 tmp = path.indexOf(File.separator, pos); -192 if (tmp > 0) { -193 pos = tmp + 1; -194 } -195 return path.substring(0, pos); -196 } -197 -198 /** -199 * Returns true if the file names (and version if it exists) of the two dependencies are sufficiently similar. -200 * -201 * @param dependency1 a dependency2 to compare -202 * @param dependency2 a dependency2 to compare -203 * @return true if the identifiers in the two supplied dependencies are equal -204 */ -205 private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) { -206 if (dependency1 == null || dependency1.getFileName() == null -207 || dependency2 == null || dependency2.getFileName() == null) { -208 return false; +184 dependenciesToRemove.add(relatedDependency); +185 } +186 +187 /** +188 * Attempts to trim a maven repo to a common base path. This is typically +189 * [drive]\[repo_location]\repository\[path1]\[path2]. +190 * +191 * @param path the path to trim +192 * @return a string representing the base path. +193 */ +194 private String getBaseRepoPath(final String path) { +195 int pos = path.indexOf("repository" + File.separator) + 11; +196 if (pos < 0) { +197 return path; +198 } +199 int tmp = path.indexOf(File.separator, pos); +200 if (tmp <= 0) { +201 return path; +202 } +203 if (tmp > 0) { +204 pos = tmp + 1; +205 } +206 tmp = path.indexOf(File.separator, pos); +207 if (tmp > 0) { +208 pos = tmp + 1; 209 } -210 final String fileName1 = dependency1.getActualFile().getName(); -211 final String fileName2 = dependency2.getActualFile().getName(); +210 return path.substring(0, pos); +211 } 212 -213 //version check -214 final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1); -215 final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2); -216 if (version1 != null && version2 != null && !version1.equals(version2)) { -217 return false; -218 } -219 -220 //filename check -221 final Matcher match1 = STARTING_TEXT_PATTERN.matcher(fileName1); -222 final Matcher match2 = STARTING_TEXT_PATTERN.matcher(fileName2); -223 if (match1.find() && match2.find()) { -224 return match1.group().equals(match2.group()); -225 } -226 -227 return false; -228 } +213 /** +214 * Returns true if the file names (and version if it exists) of the two +215 * dependencies are sufficiently similar. +216 * +217 * @param dependency1 a dependency2 to compare +218 * @param dependency2 a dependency2 to compare +219 * @return true if the identifiers in the two supplied dependencies are +220 * equal +221 */ +222 private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) { +223 if (dependency1 == null || dependency1.getFileName() == null +224 || dependency2 == null || dependency2.getFileName() == null) { +225 return false; +226 } +227 final String fileName1 = dependency1.getActualFile().getName(); +228 final String fileName2 = dependency2.getActualFile().getName(); 229 -230 /** -231 * Returns true if the CPE identifiers in the two supplied dependencies are equal. -232 * -233 * @param dependency1 a dependency2 to compare -234 * @param dependency2 a dependency2 to compare -235 * @return true if the identifiers in the two supplied dependencies are equal -236 */ -237 private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) { -238 if (dependency1 == null || dependency1.getIdentifiers() == null -239 || dependency2 == null || dependency2.getIdentifiers() == null) { -240 return false; -241 } -242 boolean matches = false; -243 int cpeCount1 = 0; -244 int cpeCount2 = 0; -245 for (Identifier i : dependency1.getIdentifiers()) { -246 if ("cpe".equals(i.getType())) { -247 cpeCount1 += 1; -248 } -249 } -250 for (Identifier i : dependency2.getIdentifiers()) { -251 if ("cpe".equals(i.getType())) { -252 cpeCount2 += 1; -253 } -254 } -255 if (cpeCount1 > 0 && cpeCount1 == cpeCount2) { -256 for (Identifier i : dependency1.getIdentifiers()) { -257 if ("cpe".equals(i.getType())) { -258 matches |= dependency2.getIdentifiers().contains(i); -259 if (!matches) { -260 break; -261 } -262 } -263 } -264 } -265 LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName()); -266 return matches; -267 } -268 -269 /** -270 * Determines if the two dependencies have the same base path. -271 * -272 * @param dependency1 a Dependency object -273 * @param dependency2 a Dependency object -274 * @return true if the base paths of the dependencies are identical -275 */ -276 private boolean hasSameBasePath(Dependency dependency1, Dependency dependency2) { -277 if (dependency1 == null || dependency2 == null) { -278 return false; -279 } -280 final File lFile = new File(dependency1.getFilePath()); -281 String left = lFile.getParent(); -282 final File rFile = new File(dependency2.getFilePath()); -283 String right = rFile.getParent(); -284 if (left == null) { -285 return right == null; -286 } -287 if (left.equalsIgnoreCase(right)) { -288 return true; -289 } -290 if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) { -291 left = getBaseRepoPath(left); -292 right = getBaseRepoPath(right); -293 } -294 if (left.equalsIgnoreCase(right)) { -295 return true; -296 } -297 //new code -298 for (Dependency child : dependency2.getRelatedDependencies()) { -299 if (hasSameBasePath(dependency1, child)) { -300 return true; -301 } -302 } -303 return false; -304 } -305 -306 /** -307 * This is likely a very broken attempt at determining if the 'left' dependency is the 'core' library in comparison to the -308 * 'right' library. -309 * -310 * @param left the dependency to test -311 * @param right the dependency to test against -312 * @return a boolean indicating whether or not the left dependency should be considered the "core" version. -313 */ -314 boolean isCore(Dependency left, Dependency right) { -315 final String leftName = left.getFileName().toLowerCase(); -316 final String rightName = right.getFileName().toLowerCase(); -317 -318 final boolean returnVal; -319 if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") -320 || rightName.contains("core") && !leftName.contains("core") -321 || rightName.contains("kernel") && !leftName.contains("kernel")) { -322 returnVal = false; -323 } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") -324 || !rightName.contains("core") && leftName.contains("core") -325 || !rightName.contains("kernel") && leftName.contains("kernel")) { -326 returnVal = true; -327 // } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) { -328 // returnVal = true; -329 // } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) { -330 // returnVal = false; -331 } else { -332 /* -333 * considered splitting the names up and comparing the components, -334 * but decided that the file name length should be sufficient as the -335 * "core" component, if this follows a normal naming protocol should -336 * be shorter: -337 * axis2-saaj-1.4.1.jar -338 * axis2-1.4.1.jar <----- -339 * axis2-kernel-1.4.1.jar -340 */ -341 returnVal = leftName.length() <= rightName.length(); +230 //version check +231 final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1); +232 final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2); +233 if (version1 != null && version2 != null && !version1.equals(version2)) { +234 return false; +235 } +236 +237 //filename check +238 final Matcher match1 = STARTING_TEXT_PATTERN.matcher(fileName1); +239 final Matcher match2 = STARTING_TEXT_PATTERN.matcher(fileName2); +240 if (match1.find() && match2.find()) { +241 return match1.group().equals(match2.group()); +242 } +243 +244 return false; +245 } +246 +247 /** +248 * Returns true if the CPE identifiers in the two supplied dependencies are +249 * equal. +250 * +251 * @param dependency1 a dependency2 to compare +252 * @param dependency2 a dependency2 to compare +253 * @return true if the identifiers in the two supplied dependencies are +254 * equal +255 */ +256 private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) { +257 if (dependency1 == null || dependency1.getIdentifiers() == null +258 || dependency2 == null || dependency2.getIdentifiers() == null) { +259 return false; +260 } +261 boolean matches = false; +262 int cpeCount1 = 0; +263 int cpeCount2 = 0; +264 for (Identifier i : dependency1.getIdentifiers()) { +265 if ("cpe".equals(i.getType())) { +266 cpeCount1 += 1; +267 } +268 } +269 for (Identifier i : dependency2.getIdentifiers()) { +270 if ("cpe".equals(i.getType())) { +271 cpeCount2 += 1; +272 } +273 } +274 if (cpeCount1 > 0 && cpeCount1 == cpeCount2) { +275 for (Identifier i : dependency1.getIdentifiers()) { +276 if ("cpe".equals(i.getType())) { +277 matches |= dependency2.getIdentifiers().contains(i); +278 if (!matches) { +279 break; +280 } +281 } +282 } +283 } +284 LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName()); +285 return matches; +286 } +287 +288 /** +289 * Determines if the two dependencies have the same base path. +290 * +291 * @param dependency1 a Dependency object +292 * @param dependency2 a Dependency object +293 * @return true if the base paths of the dependencies are identical +294 */ +295 private boolean hasSameBasePath(Dependency dependency1, Dependency dependency2) { +296 if (dependency1 == null || dependency2 == null) { +297 return false; +298 } +299 final File lFile = new File(dependency1.getFilePath()); +300 String left = lFile.getParent(); +301 final File rFile = new File(dependency2.getFilePath()); +302 String right = rFile.getParent(); +303 if (left == null) { +304 return right == null; +305 } +306 if (left.equalsIgnoreCase(right)) { +307 return true; +308 } +309 if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) { +310 left = getBaseRepoPath(left); +311 right = getBaseRepoPath(right); +312 } +313 if (left.equalsIgnoreCase(right)) { +314 return true; +315 } +316 //new code +317 for (Dependency child : dependency2.getRelatedDependencies()) { +318 if (hasSameBasePath(dependency1, child)) { +319 return true; +320 } +321 } +322 return false; +323 } +324 +325 /** +326 * Bundling Ruby gems that are identified from different .gemspec files but +327 * denote the same package path. This happens when Ruby bundler installs an +328 * application's dependencies by running "bundle install". +329 * +330 * @param dependency1 dependency to compare +331 * @param dependency2 dependency to compare +332 * @return true if the the dependencies being analyzed appear to be the +333 * same; otherwise false +334 */ +335 private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) { +336 if (dependency1 == null || dependency2 == null +337 || !dependency1.getFileName().endsWith(".gemspec") +338 || !dependency2.getFileName().endsWith(".gemspec") +339 || dependency1.getPackagePath() == null +340 || dependency2.getPackagePath() == null) { +341 return false; 342 } -343 LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName()); -344 return returnVal; -345 } +343 if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath())) { +344 return true; +345 } 346 -347 /** -348 * Compares the SHA1 hashes of two dependencies to determine if they are equal. -349 * -350 * @param dependency1 a dependency object to compare -351 * @param dependency2 a dependency object to compare -352 * @return true if the sha1 hashes of the two dependencies match; otherwise false -353 */ -354 private boolean hashesMatch(Dependency dependency1, Dependency dependency2) { -355 if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) { -356 return false; -357 } -358 return dependency1.getSha1sum().equals(dependency2.getSha1sum()); -359 } -360 -361 /** -362 * Determines if the jar is shaded and the created pom.xml identified the same CPE as the jar - if so, the pom.xml dependency -363 * should be removed. -364 * -365 * @param dependency a dependency to check -366 * @param nextDependency another dependency to check -367 * @return true if on of the dependencies is a pom.xml and the identifiers between the two collections match; otherwise false -368 */ -369 private boolean isShadedJar(Dependency dependency, Dependency nextDependency) { -370 final String mainName = dependency.getFileName().toLowerCase(); -371 final String nextName = nextDependency.getFileName().toLowerCase(); -372 if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) { -373 return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers()); -374 } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) { -375 return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers()); -376 } -377 return false; -378 } -379 -380 /** -381 * Determines which path is shortest; if path lengths are equal then we use compareTo of the string method to determine if the -382 * first path is smaller. -383 * -384 * @param left the first path to compare -385 * @param right the second path to compare -386 * @return <code>true</code> if the leftPath is the shortest; otherwise <code>false</code> +347 return false; +348 } +349 +350 /** +351 * Ruby gems installed by "bundle install" can have zero or more *.gemspec +352 * files, all of which have the same packagePath and should be grouped. If +353 * one of these gemspec is from <parent>/specifications/*.gemspec, because +354 * it is a stub with fully resolved gem meta-data created by Ruby bundler, +355 * this dependency should be the main one. Otherwise, use dependency2 as +356 * main. +357 * +358 * This method returns null if any dependency is not from *.gemspec, or the +359 * two do not have the same packagePath. In this case, they should not be +360 * grouped. +361 * +362 * @param dependency1 dependency to compare +363 * @param dependency2 dependency to compare +364 * @return the main dependency; or null if a gemspec is not included in the +365 * analysis +366 */ +367 private Dependency getMainGemspecDependency(Dependency dependency1, Dependency dependency2) { +368 if (isSameRubyGem(dependency1, dependency2)) { +369 final File lFile = dependency1.getActualFile(); +370 final File left = lFile.getParentFile(); +371 if (left != null && left.getName().equalsIgnoreCase("specifications")) { +372 return dependency1; +373 } +374 return dependency2; +375 } +376 return null; +377 } +378 +379 /** +380 * This is likely a very broken attempt at determining if the 'left' +381 * dependency is the 'core' library in comparison to the 'right' library. +382 * +383 * @param left the dependency to test +384 * @param right the dependency to test against +385 * @return a boolean indicating whether or not the left dependency should be +386 * considered the "core" version. 387 */ -388 protected boolean firstPathIsShortest(String left, String right) { -389 final String leftPath = left.replace('\\', '/'); -390 final String rightPath = right.replace('\\', '/'); +388 boolean isCore(Dependency left, Dependency right) { +389 final String leftName = left.getFileName().toLowerCase(); +390 final String rightName = right.getFileName().toLowerCase(); 391 -392 final int leftCount = countChar(leftPath, '/'); -393 final int rightCount = countChar(rightPath, '/'); -394 if (leftCount == rightCount) { -395 return leftPath.compareTo(rightPath) <= 0; -396 } else { -397 return leftCount < rightCount; -398 } -399 } -400 -401 /** -402 * Counts the number of times the character is present in the string. -403 * -404 * @param string the string to count the characters in -405 * @param c the character to count -406 * @return the number of times the character is present in the string -407 */ -408 private int countChar(String string, char c) { -409 int count = 0; -410 final int max = string.length(); -411 for (int i = 0; i < max; i++) { -412 if (c == string.charAt(i)) { -413 count++; -414 } -415 } -416 return count; -417 } -418 -419 /** -420 * Checks if the given file path is contained within a war or ear file. -421 * -422 * @param filePath the file path to check -423 * @return true if the path contains '.war\' or '.ear\'. -424 */ -425 private boolean containedInWar(String filePath) { -426 return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*"); -427 } -428 } +392 final boolean returnVal; +393 if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") +394 || rightName.contains("core") && !leftName.contains("core") +395 || rightName.contains("kernel") && !leftName.contains("kernel")) { +396 returnVal = false; +397 } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") +398 || !rightName.contains("core") && leftName.contains("core") +399 || !rightName.contains("kernel") && leftName.contains("kernel")) { +400 returnVal = true; +401 // } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) { +402 // returnVal = true; +403 // } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) { +404 // returnVal = false; +405 } else { +406 /* +407 * considered splitting the names up and comparing the components, +408 * but decided that the file name length should be sufficient as the +409 * "core" component, if this follows a normal naming protocol should +410 * be shorter: +411 * axis2-saaj-1.4.1.jar +412 * axis2-1.4.1.jar <----- +413 * axis2-kernel-1.4.1.jar +414 */ +415 returnVal = leftName.length() <= rightName.length(); +416 } +417 LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName()); +418 return returnVal; +419 } +420 +421 /** +422 * Compares the SHA1 hashes of two dependencies to determine if they are +423 * equal. +424 * +425 * @param dependency1 a dependency object to compare +426 * @param dependency2 a dependency object to compare +427 * @return true if the sha1 hashes of the two dependencies match; otherwise +428 * false +429 */ +430 private boolean hashesMatch(Dependency dependency1, Dependency dependency2) { +431 if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) { +432 return false; +433 } +434 return dependency1.getSha1sum().equals(dependency2.getSha1sum()); +435 } +436 +437 /** +438 * Determines if the jar is shaded and the created pom.xml identified the +439 * same CPE as the jar - if so, the pom.xml dependency should be removed. +440 * +441 * @param dependency a dependency to check +442 * @param nextDependency another dependency to check +443 * @return true if on of the dependencies is a pom.xml and the identifiers +444 * between the two collections match; otherwise false +445 */ +446 private boolean isShadedJar(Dependency dependency, Dependency nextDependency) { +447 final String mainName = dependency.getFileName().toLowerCase(); +448 final String nextName = nextDependency.getFileName().toLowerCase(); +449 if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) { +450 return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers()); +451 } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) { +452 return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers()); +453 } +454 return false; +455 } +456 +457 /** +458 * Determines which path is shortest; if path lengths are equal then we use +459 * compareTo of the string method to determine if the first path is smaller. +460 * +461 * @param left the first path to compare +462 * @param right the second path to compare +463 * @return <code>true</code> if the leftPath is the shortest; otherwise +464 * <code>false</code> +465 */ +466 protected boolean firstPathIsShortest(String left, String right) { +467 final String leftPath = left.replace('\\', '/'); +468 final String rightPath = right.replace('\\', '/'); +469 +470 final int leftCount = countChar(leftPath, '/'); +471 final int rightCount = countChar(rightPath, '/'); +472 if (leftCount == rightCount) { +473 return leftPath.compareTo(rightPath) <= 0; +474 } else { +475 return leftCount < rightCount; +476 } +477 } +478 +479 /** +480 * Counts the number of times the character is present in the string. +481 * +482 * @param string the string to count the characters in +483 * @param c the character to count +484 * @return the number of times the character is present in the string +485 */ +486 private int countChar(String string, char c) { +487 int count = 0; +488 final int max = string.length(); +489 for (int i = 0; i < max; i++) { +490 if (c == string.charAt(i)) { +491 count++; +492 } +493 } +494 return count; +495 } +496 +497 /** +498 * Checks if the given file path is contained within a war or ear file. +499 * +500 * @param filePath the file path to check +501 * @return true if the path contains '.war\' or '.ear\'. +502 */ +503 private boolean containedInWar(String filePath) { +504 return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*"); +505 } +506 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/Experimental.html b/xref/org/owasp/dependencycheck/analyzer/Experimental.html new file mode 100644 index 000000000..98b6949ac --- /dev/null +++ b/xref/org/owasp/dependencycheck/analyzer/Experimental.html @@ -0,0 +1,47 @@ + + + +Experimental xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +3    *
      +4    * Licensed under the Apache License, Version 2.0 (the "License");
      +5    * you may not use this file except in compliance with the License.
      +6    * You may obtain a copy of the License at
      +7    *
      +8    *     http://www.apache.org/licenses/LICENSE-2.0
      +9    *
      +10   * Unless required by applicable law or agreed to in writing, software
      +11   * distributed under the License is distributed on an "AS IS" BASIS,
      +12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      +13   * See the License for the specific language governing permissions and
      +14   * limitations under the License.
      +15   *
      +16   * Copyright (c) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.analyzer;
      +19  
      +20  import java.lang.annotation.ElementType;
      +21  import java.lang.annotation.Retention;
      +22  import java.lang.annotation.RetentionPolicy;
      +23  import java.lang.annotation.Target;
      +24  
      +25  /**
      +26   * Annotation used to flag an analyzer as experimental.
      +27   *
      +28   * @author jeremy long
      +29   */
      +30  @Retention(RetentionPolicy.RUNTIME)
      +31  @Target(ElementType.TYPE)
      +32  public @interface Experimental {
      +33  
      +34  }
      +
      +
      + + + diff --git a/xref/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.html index 6d2cc1c4f..623b7e3ac 100644 --- a/xref/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.html @@ -75,58 +75,55 @@ 67 } 68 //</editor-fold> 69 -70 // Python init files -71 private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[] { -72 "__init__.py", -73 "__init__.pyc", -74 "__init__.pyo" -75 }); -76 -77 /** -78 * Collects information about the file name. -79 * -80 * @param dependency the dependency to analyze. -81 * @param engine the engine that is scanning the dependencies -82 * @throws AnalysisException is thrown if there is an error reading the JAR file. -83 */ -84 @Override -85 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -86 -87 //strip any path information that may get added by ArchiveAnalyzer, etc. -88 final File f = dependency.getActualFile(); -89 final String fileName = FilenameUtils.removeExtension(f.getName()); -90 -91 //add version evidence -92 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName); -93 if (version != null) { -94 // If the version number is just a number like 2 or 23, reduce the confidence -95 // a shade. This should hopefully correct for cases like log4j.jar or -96 // struts2-core.jar -97 if (version.getVersionParts() == null || version.getVersionParts().size() < 2) { -98 dependency.getVersionEvidence().addEvidence("file", "name", -99 version.toString(), Confidence.MEDIUM); -100 } else { +70 /** +71 * Python init files +72 */ +73 private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{ +74 "__init__.py", +75 "__init__.pyc", +76 "__init__.pyo", +77 }); +78 +79 /** +80 * Collects information about the file name. +81 * +82 * @param dependency the dependency to analyze. +83 * @param engine the engine that is scanning the dependencies +84 * @throws AnalysisException is thrown if there is an error reading the JAR +85 * file. +86 */ +87 @Override +88 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +89 +90 //strip any path information that may get added by ArchiveAnalyzer, etc. +91 final File f = dependency.getActualFile(); +92 final String fileName = FilenameUtils.removeExtension(f.getName()); +93 +94 //add version evidence +95 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName); +96 if (version != null) { +97 // If the version number is just a number like 2 or 23, reduce the confidence +98 // a shade. This should hopefully correct for cases like log4j.jar or +99 // struts2-core.jar +100 if (version.getVersionParts() == null || version.getVersionParts().size() < 2) { 101 dependency.getVersionEvidence().addEvidence("file", "name", -102 version.toString(), Confidence.HIGHEST); -103 } -104 dependency.getVersionEvidence().addEvidence("file", "name", -105 fileName, Confidence.MEDIUM); -106 } -107 -108 //add as vendor and product evidence -109 if (fileName.contains("-")) { -110 dependency.getProductEvidence().addEvidence("file", "name", -111 fileName, Confidence.HIGHEST); -112 dependency.getVendorEvidence().addEvidence("file", "name", -113 fileName, Confidence.HIGHEST); -114 } else if (!IGNORED_FILES.accept(f)) { -115 dependency.getProductEvidence().addEvidence("file", "name", -116 fileName, Confidence.HIGH); -117 dependency.getVendorEvidence().addEvidence("file", "name", -118 fileName, Confidence.HIGH); -119 } -120 } -121 } +102 version.toString(), Confidence.MEDIUM); +103 } else { +104 dependency.getVersionEvidence().addEvidence("file", "version", +105 version.toString(), Confidence.HIGHEST); +106 } +107 dependency.getVersionEvidence().addEvidence("file", "name", +108 fileName, Confidence.MEDIUM); +109 } +110 +111 if (!IGNORED_FILES.accept(f)) { +112 dependency.getProductEvidence().addEvidence("file", "name", +113 fileName, Confidence.HIGH); +114 dependency.getVendorEvidence().addEvidence("file", "name", +115 fileName, Confidence.HIGH); +116 } +117 } +118 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html index b4316c471..973da820f 100644 --- a/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html @@ -37,38 +37,38 @@ 29 import java.util.Collections; 30 import java.util.Enumeration; 31 import java.util.HashMap; -32 import java.util.Iterator; -33 import java.util.List; -34 import java.util.Map; -35 import java.util.Map.Entry; -36 import java.util.Properties; -37 import java.util.Set; -38 import java.util.StringTokenizer; -39 import java.util.jar.Attributes; -40 import java.util.jar.JarEntry; -41 import java.util.jar.JarFile; -42 import java.util.jar.Manifest; -43 import java.util.regex.Pattern; -44 import java.util.zip.ZipEntry; -45 import org.apache.commons.compress.utils.IOUtils; -46 import org.apache.commons.io.FilenameUtils; -47 import org.jsoup.Jsoup; -48 import org.owasp.dependencycheck.Engine; -49 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -50 import org.owasp.dependencycheck.dependency.Confidence; -51 import org.owasp.dependencycheck.dependency.Dependency; -52 import org.owasp.dependencycheck.dependency.EvidenceCollection; -53 import org.owasp.dependencycheck.utils.FileFilterBuilder; -54 import org.owasp.dependencycheck.xml.pom.License; -55 import org.owasp.dependencycheck.xml.pom.PomUtils; -56 import org.owasp.dependencycheck.xml.pom.Model; -57 import org.owasp.dependencycheck.utils.FileUtils; -58 import org.owasp.dependencycheck.utils.Settings; -59 import org.slf4j.Logger; -60 import org.slf4j.LoggerFactory; -61 -62 /** -63 * Used to load a JAR file and collect information that can be used to determine the associated CPE. +32 import java.util.List; +33 import java.util.Map; +34 import java.util.Map.Entry; +35 import java.util.Properties; +36 import java.util.Set; +37 import java.util.StringTokenizer; +38 import java.util.jar.Attributes; +39 import java.util.jar.JarEntry; +40 import java.util.jar.JarFile; +41 import java.util.jar.Manifest; +42 import java.util.regex.Pattern; +43 import java.util.zip.ZipEntry; +44 import org.apache.commons.compress.utils.IOUtils; +45 import org.apache.commons.io.FilenameUtils; +46 import org.jsoup.Jsoup; +47 import org.owasp.dependencycheck.Engine; +48 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +49 import org.owasp.dependencycheck.dependency.Confidence; +50 import org.owasp.dependencycheck.dependency.Dependency; +51 import org.owasp.dependencycheck.dependency.EvidenceCollection; +52 import org.owasp.dependencycheck.utils.FileFilterBuilder; +53 import org.owasp.dependencycheck.xml.pom.License; +54 import org.owasp.dependencycheck.xml.pom.PomUtils; +55 import org.owasp.dependencycheck.xml.pom.Model; +56 import org.owasp.dependencycheck.utils.FileUtils; +57 import org.owasp.dependencycheck.utils.Settings; +58 import org.slf4j.Logger; +59 import org.slf4j.LoggerFactory; +60 +61 /** +62 * Used to load a JAR file and collect information that can be used to determine +63 * the associated CPE. 64 * 65 * @author Jeremy Long 66 */ @@ -80,1132 +80,1161 @@ 72 */ 73 private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class); 74 /** -75 * The count of directories created during analysis. This is used for creating temporary directories. -76 */ -77 private static int dirCount = 0; -78 /** -79 * The system independent newline character. -80 */ -81 private static final String NEWLINE = System.getProperty("line.separator"); -82 /** -83 * A list of values in the manifest to ignore as they only result in false positives. -84 */ -85 private static final Set<String> IGNORE_VALUES = newHashSet( -86 "Sun Java System Application Server"); -87 /** -88 * A list of elements in the manifest to ignore. -89 */ -90 private static final Set<String> IGNORE_KEYS = newHashSet( -91 "built-by", -92 "created-by", -93 "builtby", -94 "createdby", -95 "build-jdk", -96 "buildjdk", -97 "ant-version", -98 "antversion", -99 "dynamicimportpackage", -100 "dynamicimport-package", -101 "dynamic-importpackage", -102 "dynamic-import-package", -103 "import-package", -104 "ignore-package", -105 "export-package", -106 "importpackage", -107 "ignorepackage", -108 "exportpackage", -109 "sealed", -110 "manifest-version", -111 "archiver-version", -112 "manifestversion", -113 "archiverversion", -114 "classpath", -115 "class-path", -116 "tool", -117 "bundle-manifestversion", -118 "bundlemanifestversion", -119 "bundle-vendor", -120 "include-resource", -121 "embed-dependency", -122 "ipojo-components", -123 "ipojo-extension", -124 "eclipse-sourcereferences"); -125 /** -126 * Deprecated Jar manifest attribute, that is, nonetheless, useful for analysis. -127 */ -128 @SuppressWarnings("deprecation") -129 private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID -130 .toString(); -131 /** -132 * item in some manifest, should be considered medium confidence. -133 */ -134 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 -135 /** -136 * item in some manifest, should be considered medium confidence. -137 */ -138 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 -139 /** -140 * item in some manifest, should be considered medium confidence. -141 */ -142 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core -143 /** -144 * A pattern to detect HTML within text. -145 */ -146 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); -147 -148 //</editor-fold> -149 /** -150 * Constructs a new JarAnalyzer. -151 */ -152 public JarAnalyzer() { -153 } -154 -155 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> -156 /** -157 * The name of the analyzer. -158 */ -159 private static final String ANALYZER_NAME = "Jar Analyzer"; -160 /** -161 * The phase that this analyzer is intended to run in. -162 */ -163 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -164 /** -165 * The set of file extensions supported by this analyzer. -166 */ -167 private static final String[] EXTENSIONS = {"jar", "war"}; -168 -169 /** -170 * The file filter used to determine which files this analyzer supports. -171 */ -172 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); -173 -174 /** -175 * Returns the FileFilter. -176 * -177 * @return the FileFilter -178 */ -179 @Override -180 protected FileFilter getFileFilter() { -181 return FILTER; -182 } -183 -184 /** -185 * Returns the name of the analyzer. -186 * -187 * @return the name of the analyzer. -188 */ -189 @Override -190 public String getName() { -191 return ANALYZER_NAME; -192 } -193 -194 /** -195 * Returns the phase that the analyzer is intended to run in. -196 * -197 * @return the phase that the analyzer is intended to run in. -198 */ -199 @Override -200 public AnalysisPhase getAnalysisPhase() { -201 return ANALYSIS_PHASE; -202 } -203 //</editor-fold> -204 -205 /** -206 * Returns the key used in the properties file to reference the analyzer's enabled property. -207 * -208 * @return the analyzer's enabled property setting key -209 */ -210 @Override -211 protected String getAnalyzerEnabledSettingKey() { -212 return Settings.KEYS.ANALYZER_JAR_ENABLED; -213 } -214 -215 /** -216 * Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE -217 * information. -218 * -219 * @param dependency the dependency to analyze. -220 * @param engine the engine that is scanning the dependencies -221 * @throws AnalysisException is thrown if there is an error reading the JAR file. -222 */ -223 @Override -224 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -225 try { -226 final List<ClassNameInformation> classNames = collectClassNames(dependency); -227 final String fileName = dependency.getFileName().toLowerCase(); -228 if (classNames.isEmpty() -229 && (fileName.endsWith("-sources.jar") -230 || fileName.endsWith("-javadoc.jar") -231 || fileName.endsWith("-src.jar") -232 || fileName.endsWith("-doc.jar"))) { -233 engine.getDependencies().remove(dependency); -234 } -235 final boolean hasManifest = parseManifest(dependency, classNames); -236 final boolean hasPOM = analyzePOM(dependency, classNames, engine); -237 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); -238 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); -239 } catch (IOException ex) { -240 throw new AnalysisException("Exception occurred reading the JAR file.", ex); -241 } -242 } -243 -244 /** -245 * Attempts to find a pom.xml within the JAR file. If found it extracts information and adds it to the evidence. This will -246 * attempt to interpolate the strings contained within the pom.properties if one exists. -247 * -248 * @param dependency the dependency being analyzed -249 * @param classes a collection of class name information -250 * @param engine the analysis engine, used to add additional dependencies -251 * @throws AnalysisException is thrown if there is an exception parsing the pom -252 * @return whether or not evidence was added to the dependency -253 */ -254 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { -255 boolean foundSomething = false; -256 final JarFile jar; -257 try { -258 jar = new JarFile(dependency.getActualFilePath()); -259 } catch (IOException ex) { -260 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath()); -261 LOGGER.trace("", ex); -262 return false; -263 } -264 List<String> pomEntries; -265 try { -266 pomEntries = retrievePomListing(jar); -267 } catch (IOException ex) { -268 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath()); -269 LOGGER.trace("", ex); -270 return false; -271 } -272 File externalPom = null; -273 if (pomEntries.isEmpty()) { -274 final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom"; -275 externalPom = new File(pomPath); -276 if (externalPom.isFile()) { -277 pomEntries.add(pomPath); -278 } else { -279 return false; -280 } -281 } -282 for (String path : pomEntries) { -283 LOGGER.debug("Reading pom entry: {}", path); -284 Properties pomProperties = null; -285 try { -286 if (externalPom == null) { -287 pomProperties = retrievePomProperties(path, jar); -288 } -289 } catch (IOException ex) { -290 LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex); -291 } -292 Model pom = null; -293 try { -294 if (pomEntries.size() > 1) { -295 //extract POM to its own directory and add it as its own dependency -296 final Dependency newDependency = new Dependency(); -297 pom = extractPom(path, jar, newDependency); -298 -299 final String displayPath = String.format("%s%s%s", -300 dependency.getFilePath(), -301 File.separator, -302 path); -303 final String displayName = String.format("%s%s%s", -304 dependency.getFileName(), -305 File.separator, -306 path); -307 -308 newDependency.setFileName(displayName); -309 newDependency.setFilePath(displayPath); -310 pom.processProperties(pomProperties); -311 setPomEvidence(newDependency, pom, null); -312 engine.getDependencies().add(newDependency); -313 Collections.sort(engine.getDependencies()); -314 } else { -315 if (externalPom == null) { -316 pom = PomUtils.readPom(path, jar); -317 } else { -318 pom = PomUtils.readPom(externalPom); -319 } -320 pom.processProperties(pomProperties); -321 foundSomething |= setPomEvidence(dependency, pom, classes); -322 } -323 } catch (AnalysisException ex) { -324 LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath()); -325 LOGGER.trace("", ex); -326 } -327 } -328 return foundSomething; -329 } -330 -331 /** -332 * Given a path to a pom.xml within a JarFile, this method attempts to load a sibling pom.properties if one exists. -333 * -334 * @param path the path to the pom.xml within the JarFile -335 * @param jar the JarFile to load the pom.properties from -336 * @return a Properties object or null if no pom.properties was found -337 * @throws IOException thrown if there is an exception reading the pom.properties -338 */ -339 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { -340 Properties pomProperties = null; -341 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; -342 final ZipEntry propEntry = jar.getEntry(propPath); -343 if (propEntry != null) { -344 Reader reader = null; -345 try { -346 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); -347 pomProperties = new Properties(); -348 pomProperties.load(reader); -349 LOGGER.debug("Read pom.properties: {}", propPath); -350 } finally { -351 if (reader != null) { -352 try { -353 reader.close(); -354 } catch (IOException ex) { -355 LOGGER.trace("close error", ex); -356 } -357 } -358 } -359 } -360 return pomProperties; -361 } -362 -363 /** -364 * Searches a JarFile for pom.xml entries and returns a listing of these entries. -365 * -366 * @param jar the JarFile to search -367 * @return a list of pom.xml entries -368 * @throws IOException thrown if there is an exception reading a JarEntry -369 */ -370 private List<String> retrievePomListing(final JarFile jar) throws IOException { -371 final List<String> pomEntries = new ArrayList<String>(); -372 final Enumeration<JarEntry> entries = jar.entries(); -373 while (entries.hasMoreElements()) { -374 final JarEntry entry = entries.nextElement(); -375 final String entryName = (new File(entry.getName())).getName().toLowerCase(); -376 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { -377 LOGGER.trace("POM Entry found: {}", entry.getName()); -378 pomEntries.add(entry.getName()); -379 } -380 } -381 return pomEntries; -382 } -383 -384 /** -385 * Retrieves the specified POM from a jar file and converts it to a Model. -386 * -387 * @param path the path to the pom.xml file within the jar file -388 * @param jar the jar file to extract the pom from -389 * @param dependency the dependency being analyzed -390 * @return returns the POM object -391 * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM -392 * {@link org.owasp.dependencycheck.xml.pom.Model} object -393 */ -394 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { -395 InputStream input = null; -396 FileOutputStream fos = null; -397 final File tmpDir = getNextTempDirectory(); -398 final File file = new File(tmpDir, "pom.xml"); -399 try { -400 final ZipEntry entry = jar.getEntry(path); -401 input = jar.getInputStream(entry); -402 fos = new FileOutputStream(file); -403 IOUtils.copy(input, fos); -404 dependency.setActualFilePath(file.getAbsolutePath()); -405 } catch (IOException ex) { -406 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath()); -407 LOGGER.error("", ex); -408 } finally { -409 closeStream(fos); -410 closeStream(input); -411 } -412 return PomUtils.readPom(file); -413 } -414 -415 /** -416 * Silently closes an input stream ignoring errors. -417 * -418 * @param stream an input stream to close -419 */ -420 private void closeStream(InputStream stream) { -421 if (stream != null) { -422 try { -423 stream.close(); -424 } catch (IOException ex) { -425 LOGGER.trace("", ex); -426 } -427 } -428 } -429 -430 /** -431 * Silently closes an output stream ignoring errors. -432 * -433 * @param stream an output stream to close -434 */ -435 private void closeStream(OutputStream stream) { -436 if (stream != null) { -437 try { -438 stream.close(); -439 } catch (IOException ex) { -440 LOGGER.trace("", ex); -441 } -442 } -443 } -444 -445 /** -446 * Sets evidence from the pom on the supplied dependency. -447 * -448 * @param dependency the dependency to set data on -449 * @param pom the information from the pom -450 * @param classes a collection of ClassNameInformation - containing data about the fully qualified class names within the JAR -451 * file being analyzed -452 * @return true if there was evidence within the pom that we could use; otherwise false -453 */ -454 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { -455 boolean foundSomething = false; -456 boolean addAsIdentifier = true; -457 if (pom == null) { -458 return foundSomething; -459 } -460 String groupid = pom.getGroupId(); -461 String parentGroupId = pom.getParentGroupId(); -462 String artifactid = pom.getArtifactId(); -463 String parentArtifactId = pom.getParentArtifactId(); -464 String version = pom.getVersion(); -465 String parentVersion = pom.getParentVersion(); -466 -467 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { -468 parentGroupId = null; -469 parentArtifactId = null; -470 parentVersion = null; -471 } -472 -473 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { -474 groupid = parentGroupId; -475 } -476 -477 final String originalGroupID = groupid; -478 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { -479 groupid = groupid.substring(4); -480 } -481 -482 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { -483 artifactid = parentArtifactId; -484 } -485 -486 final String originalArtifactID = artifactid; -487 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { -488 artifactid = artifactid.substring(4); -489 } -490 -491 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { -492 version = parentVersion; -493 } -494 -495 if (groupid != null && !groupid.isEmpty()) { -496 foundSomething = true; -497 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); -498 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); -499 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); -500 addMatchingValues(classes, groupid, dependency.getProductEvidence()); -501 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { -502 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); -503 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); -504 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); -505 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); -506 } -507 } else { -508 addAsIdentifier = false; -509 } -510 -511 if (artifactid != null && !artifactid.isEmpty()) { -512 foundSomething = true; -513 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); -514 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); -515 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); -516 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); -517 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { -518 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); -519 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); -520 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); -521 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); -522 } -523 } else { -524 addAsIdentifier = false; -525 } -526 -527 if (version != null && !version.isEmpty()) { -528 foundSomething = true; -529 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); -530 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { -531 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); -532 } -533 } else { -534 addAsIdentifier = false; -535 } -536 -537 if (addAsIdentifier) { -538 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); -539 } -540 -541 // org name -542 final String org = pom.getOrganization(); -543 if (org != null && !org.isEmpty()) { -544 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); -545 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); -546 addMatchingValues(classes, org, dependency.getVendorEvidence()); -547 addMatchingValues(classes, org, dependency.getProductEvidence()); -548 } -549 //pom name -550 final String pomName = pom.getName(); -551 if (pomName -552 != null && !pomName.isEmpty()) { -553 foundSomething = true; -554 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -555 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -556 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); -557 addMatchingValues(classes, pomName, dependency.getProductEvidence()); -558 } -559 -560 //Description -561 final String description = pom.getDescription(); -562 if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { -563 foundSomething = true; -564 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); -565 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); -566 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); -567 } -568 -569 extractLicense(pom, dependency); -570 return foundSomething; -571 } -572 -573 /** -574 * Analyzes the path information of the classes contained within the JarAnalyzer to try and determine possible vendor or -575 * product names. If any are found they are stored in the packageVendor and packageProduct hashSets. -576 * -577 * @param classNames a list of class names -578 * @param dependency a dependency to analyze -579 * @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence. -580 */ -581 protected void analyzePackageNames(List<ClassNameInformation> classNames, -582 Dependency dependency, boolean addPackagesAsEvidence) { -583 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); -584 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); -585 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); -586 -587 final int classCount = classNames.size(); -588 final EvidenceCollection vendor = dependency.getVendorEvidence(); -589 final EvidenceCollection product = dependency.getProductEvidence(); -590 -591 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { -592 final float ratio = entry.getValue() / (float) classCount; -593 if (ratio > 0.5) { -594 //TODO remove weighting -595 vendor.addWeighting(entry.getKey()); -596 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -597 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -598 } -599 } -600 } -601 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { -602 final float ratio = entry.getValue() / (float) classCount; -603 if (ratio > 0.5) { -604 product.addWeighting(entry.getKey()); -605 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -606 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -607 } -608 } -609 } -610 } -611 -612 /** -613 * <p> -614 * Reads the manifest from the JAR file and collects the entries. Some vendorKey entries are:</p> -615 * <ul><li>Implementation Title</li> -616 * <li>Implementation Version</li> <li>Implementation Vendor</li> -617 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle Version</li> <li>Bundle Vendor</li> <li>Bundle -618 * Description</li> <li>Main Class</li> </ul> -619 * However, all but a handful of specific entries are read in. -620 * -621 * @param dependency A reference to the dependency -622 * @param classInformation a collection of class information -623 * @return whether evidence was identified parsing the manifest -624 * @throws IOException if there is an issue reading the JAR file -625 */ -626 protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException { -627 boolean foundSomething = false; -628 JarFile jar = null; -629 try { -630 jar = new JarFile(dependency.getActualFilePath()); -631 final Manifest manifest = jar.getManifest(); -632 if (manifest == null) { -633 //don't log this for javadoc or sources jar files -634 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") -635 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") -636 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") -637 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { -638 LOGGER.debug("Jar file '{}' does not contain a manifest.", -639 dependency.getFileName()); -640 } -641 return false; -642 } -643 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); -644 final EvidenceCollection productEvidence = dependency.getProductEvidence(); -645 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); -646 -647 String source = "Manifest"; -648 String specificationVersion = null; -649 boolean hasImplementationVersion = false; -650 -651 Attributes atts = manifest.getMainAttributes(); -652 for (Entry<Object, Object> entry : atts.entrySet()) { -653 String key = entry.getKey().toString(); -654 String value = atts.getValue(key); -655 if (HTML_DETECTION_PATTERN.matcher(value).find()) { -656 value = Jsoup.parse(value).text(); -657 } -658 if (IGNORE_VALUES.contains(value)) { -659 continue; -660 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { -661 foundSomething = true; -662 productEvidence.addEvidence(source, key, value, Confidence.HIGH); -663 addMatchingValues(classInformation, value, productEvidence); -664 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { -665 hasImplementationVersion = true; -666 foundSomething = true; -667 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -668 } else if ("specification-version".equalsIgnoreCase(key)) { -669 specificationVersion = key; -670 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { -671 foundSomething = true; -672 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -673 addMatchingValues(classInformation, value, vendorEvidence); -674 } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { -675 foundSomething = true; -676 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -677 addMatchingValues(classInformation, value, vendorEvidence); -678 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { -679 foundSomething = true; -680 addDescription(dependency, value, "manifest", key); -681 //productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -682 addMatchingValues(classInformation, value, productEvidence); -683 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { -684 foundSomething = true; -685 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -686 addMatchingValues(classInformation, value, productEvidence); -687 // //the following caused false positives. -688 // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { -689 // foundSomething = true; -690 // vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -691 // addMatchingValues(classInformation, value, vendorEvidence); -692 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { -693 foundSomething = true; -694 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -695 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { -696 continue; -697 //skipping main class as if this has important information to add -698 // it will be added during class name analysis... if other fields -699 // have the information from the class name then they will get added... -700 // foundSomething = true; -701 // productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -702 // vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -703 // addMatchingValues(classInformation, value, vendorEvidence); -704 // addMatchingValues(classInformation, value, productEvidence); -705 } else { -706 key = key.toLowerCase(); -707 if (!IGNORE_KEYS.contains(key) -708 && !key.endsWith("jdk") -709 && !key.contains("lastmodified") -710 && !key.endsWith("package") -711 && !key.endsWith("classpath") -712 && !key.endsWith("class-path") -713 && !key.endsWith("-scm") //todo change this to a regex? -714 && !key.startsWith("scm-") -715 && !value.trim().startsWith("scm:") -716 && !isImportPackage(key, value) -717 && !isPackage(key, value)) { -718 -719 foundSomething = true; -720 if (key.contains("version")) { -721 if (!key.contains("specification")) { -722 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -723 } -724 } else if ("build-id".equals(key)) { -725 int pos = value.indexOf('('); -726 if (pos >= 0) { -727 value = value.substring(0, pos - 1); -728 } -729 pos = value.indexOf('['); -730 if (pos >= 0) { -731 value = value.substring(0, pos - 1); -732 } -733 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -734 } else if (key.contains("title")) { -735 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -736 addMatchingValues(classInformation, value, productEvidence); -737 } else if (key.contains("vendor")) { -738 if (key.contains("specification")) { -739 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -740 } else { -741 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -742 addMatchingValues(classInformation, value, vendorEvidence); -743 } -744 } else if (key.contains("name")) { -745 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -746 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -747 addMatchingValues(classInformation, value, vendorEvidence); -748 addMatchingValues(classInformation, value, productEvidence); -749 } else if (key.contains("license")) { -750 addLicense(dependency, value); -751 } else { -752 if (key.contains("description")) { -753 addDescription(dependency, value, "manifest", key); +75 * The count of directories created during analysis. This is used for +76 * creating temporary directories. +77 */ +78 private static int dirCount = 0; +79 /** +80 * The system independent newline character. +81 */ +82 private static final String NEWLINE = System.getProperty("line.separator"); +83 /** +84 * A list of values in the manifest to ignore as they only result in false +85 * positives. +86 */ +87 private static final Set<String> IGNORE_VALUES = newHashSet( +88 "Sun Java System Application Server"); +89 /** +90 * A list of elements in the manifest to ignore. +91 */ +92 private static final Set<String> IGNORE_KEYS = newHashSet( +93 "built-by", +94 "created-by", +95 "builtby", +96 "createdby", +97 "build-jdk", +98 "buildjdk", +99 "ant-version", +100 "antversion", +101 "dynamicimportpackage", +102 "dynamicimport-package", +103 "dynamic-importpackage", +104 "dynamic-import-package", +105 "import-package", +106 "ignore-package", +107 "export-package", +108 "importpackage", +109 "ignorepackage", +110 "exportpackage", +111 "sealed", +112 "manifest-version", +113 "archiver-version", +114 "manifestversion", +115 "archiverversion", +116 "classpath", +117 "class-path", +118 "tool", +119 "bundle-manifestversion", +120 "bundlemanifestversion", +121 "bundle-vendor", +122 "include-resource", +123 "embed-dependency", +124 "ipojo-components", +125 "ipojo-extension", +126 "eclipse-sourcereferences"); +127 /** +128 * Deprecated Jar manifest attribute, that is, nonetheless, useful for +129 * analysis. +130 */ +131 @SuppressWarnings("deprecation") +132 private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID +133 .toString(); +134 /** +135 * item in some manifest, should be considered medium confidence. +136 */ +137 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 +138 /** +139 * item in some manifest, should be considered medium confidence. +140 */ +141 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 +142 /** +143 * item in some manifest, should be considered medium confidence. +144 */ +145 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core +146 /** +147 * A pattern to detect HTML within text. +148 */ +149 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); +150 +151 //</editor-fold> +152 /** +153 * Constructs a new JarAnalyzer. +154 */ +155 public JarAnalyzer() { +156 } +157 +158 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> +159 /** +160 * The name of the analyzer. +161 */ +162 private static final String ANALYZER_NAME = "Jar Analyzer"; +163 /** +164 * The phase that this analyzer is intended to run in. +165 */ +166 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +167 /** +168 * The set of file extensions supported by this analyzer. +169 */ +170 private static final String[] EXTENSIONS = {"jar", "war"}; +171 +172 /** +173 * The file filter used to determine which files this analyzer supports. +174 */ +175 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +176 +177 /** +178 * Returns the FileFilter. +179 * +180 * @return the FileFilter +181 */ +182 @Override +183 protected FileFilter getFileFilter() { +184 return FILTER; +185 } +186 +187 /** +188 * Returns the name of the analyzer. +189 * +190 * @return the name of the analyzer. +191 */ +192 @Override +193 public String getName() { +194 return ANALYZER_NAME; +195 } +196 +197 /** +198 * Returns the phase that the analyzer is intended to run in. +199 * +200 * @return the phase that the analyzer is intended to run in. +201 */ +202 @Override +203 public AnalysisPhase getAnalysisPhase() { +204 return ANALYSIS_PHASE; +205 } +206 //</editor-fold> +207 +208 /** +209 * Returns the key used in the properties file to reference the analyzer's +210 * enabled property. +211 * +212 * @return the analyzer's enabled property setting key +213 */ +214 @Override +215 protected String getAnalyzerEnabledSettingKey() { +216 return Settings.KEYS.ANALYZER_JAR_ENABLED; +217 } +218 +219 /** +220 * Loads a specified JAR file and collects information from the manifest and +221 * checksums to identify the correct CPE information. +222 * +223 * @param dependency the dependency to analyze. +224 * @param engine the engine that is scanning the dependencies +225 * @throws AnalysisException is thrown if there is an error reading the JAR +226 * file. +227 */ +228 @Override +229 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +230 try { +231 final List<ClassNameInformation> classNames = collectClassNames(dependency); +232 final String fileName = dependency.getFileName().toLowerCase(); +233 if (classNames.isEmpty() +234 && (fileName.endsWith("-sources.jar") +235 || fileName.endsWith("-javadoc.jar") +236 || fileName.endsWith("-src.jar") +237 || fileName.endsWith("-doc.jar"))) { +238 engine.getDependencies().remove(dependency); +239 } +240 final boolean hasManifest = parseManifest(dependency, classNames); +241 final boolean hasPOM = analyzePOM(dependency, classNames, engine); +242 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); +243 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); +244 } catch (IOException ex) { +245 throw new AnalysisException("Exception occurred reading the JAR file.", ex); +246 } +247 } +248 +249 /** +250 * Attempts to find a pom.xml within the JAR file. If found it extracts +251 * information and adds it to the evidence. This will attempt to interpolate +252 * the strings contained within the pom.properties if one exists. +253 * +254 * @param dependency the dependency being analyzed +255 * @param classes a collection of class name information +256 * @param engine the analysis engine, used to add additional dependencies +257 * @throws AnalysisException is thrown if there is an exception parsing the +258 * pom +259 * @return whether or not evidence was added to the dependency +260 */ +261 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { +262 boolean foundSomething = false; +263 final JarFile jar; +264 try { +265 jar = new JarFile(dependency.getActualFilePath()); +266 } catch (IOException ex) { +267 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath()); +268 LOGGER.trace("", ex); +269 return false; +270 } +271 List<String> pomEntries; +272 try { +273 pomEntries = retrievePomListing(jar); +274 } catch (IOException ex) { +275 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath()); +276 LOGGER.trace("", ex); +277 return false; +278 } +279 File externalPom = null; +280 if (pomEntries.isEmpty()) { +281 final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom"; +282 externalPom = new File(pomPath); +283 if (externalPom.isFile()) { +284 pomEntries.add(pomPath); +285 } else { +286 return false; +287 } +288 } +289 for (String path : pomEntries) { +290 LOGGER.debug("Reading pom entry: {}", path); +291 Properties pomProperties = null; +292 try { +293 if (externalPom == null) { +294 pomProperties = retrievePomProperties(path, jar); +295 } +296 } catch (IOException ex) { +297 LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex); +298 } +299 Model pom = null; +300 try { +301 if (pomEntries.size() > 1) { +302 //extract POM to its own directory and add it as its own dependency +303 final Dependency newDependency = new Dependency(); +304 pom = extractPom(path, jar, newDependency); +305 +306 final String displayPath = String.format("%s%s%s", +307 dependency.getFilePath(), +308 File.separator, +309 path); +310 final String displayName = String.format("%s%s%s", +311 dependency.getFileName(), +312 File.separator, +313 path); +314 +315 newDependency.setFileName(displayName); +316 newDependency.setFilePath(displayPath); +317 pom.processProperties(pomProperties); +318 setPomEvidence(newDependency, pom, null); +319 engine.getDependencies().add(newDependency); +320 Collections.sort(engine.getDependencies()); +321 } else { +322 if (externalPom == null) { +323 pom = PomUtils.readPom(path, jar); +324 } else { +325 pom = PomUtils.readPom(externalPom); +326 } +327 pom.processProperties(pomProperties); +328 foundSomething |= setPomEvidence(dependency, pom, classes); +329 } +330 } catch (AnalysisException ex) { +331 LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath()); +332 LOGGER.trace("", ex); +333 } +334 } +335 return foundSomething; +336 } +337 +338 /** +339 * Given a path to a pom.xml within a JarFile, this method attempts to load +340 * a sibling pom.properties if one exists. +341 * +342 * @param path the path to the pom.xml within the JarFile +343 * @param jar the JarFile to load the pom.properties from +344 * @return a Properties object or null if no pom.properties was found +345 * @throws IOException thrown if there is an exception reading the +346 * pom.properties +347 */ +348 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { +349 Properties pomProperties = null; +350 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; +351 final ZipEntry propEntry = jar.getEntry(propPath); +352 if (propEntry != null) { +353 Reader reader = null; +354 try { +355 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); +356 pomProperties = new Properties(); +357 pomProperties.load(reader); +358 LOGGER.debug("Read pom.properties: {}", propPath); +359 } finally { +360 if (reader != null) { +361 try { +362 reader.close(); +363 } catch (IOException ex) { +364 LOGGER.trace("close error", ex); +365 } +366 } +367 } +368 } +369 return pomProperties; +370 } +371 +372 /** +373 * Searches a JarFile for pom.xml entries and returns a listing of these +374 * entries. +375 * +376 * @param jar the JarFile to search +377 * @return a list of pom.xml entries +378 * @throws IOException thrown if there is an exception reading a JarEntry +379 */ +380 private List<String> retrievePomListing(final JarFile jar) throws IOException { +381 final List<String> pomEntries = new ArrayList<String>(); +382 final Enumeration<JarEntry> entries = jar.entries(); +383 while (entries.hasMoreElements()) { +384 final JarEntry entry = entries.nextElement(); +385 final String entryName = (new File(entry.getName())).getName().toLowerCase(); +386 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { +387 LOGGER.trace("POM Entry found: {}", entry.getName()); +388 pomEntries.add(entry.getName()); +389 } +390 } +391 return pomEntries; +392 } +393 +394 /** +395 * Retrieves the specified POM from a jar file and converts it to a Model. +396 * +397 * @param path the path to the pom.xml file within the jar file +398 * @param jar the jar file to extract the pom from +399 * @param dependency the dependency being analyzed +400 * @return returns the POM object +401 * @throws AnalysisException is thrown if there is an exception extracting +402 * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object +403 */ +404 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { +405 InputStream input = null; +406 FileOutputStream fos = null; +407 final File tmpDir = getNextTempDirectory(); +408 final File file = new File(tmpDir, "pom.xml"); +409 try { +410 final ZipEntry entry = jar.getEntry(path); +411 input = jar.getInputStream(entry); +412 fos = new FileOutputStream(file); +413 IOUtils.copy(input, fos); +414 dependency.setActualFilePath(file.getAbsolutePath()); +415 } catch (IOException ex) { +416 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath()); +417 LOGGER.error("", ex); +418 } finally { +419 closeStream(fos); +420 closeStream(input); +421 } +422 return PomUtils.readPom(file); +423 } +424 +425 /** +426 * Silently closes an input stream ignoring errors. +427 * +428 * @param stream an input stream to close +429 */ +430 private void closeStream(InputStream stream) { +431 if (stream != null) { +432 try { +433 stream.close(); +434 } catch (IOException ex) { +435 LOGGER.trace("", ex); +436 } +437 } +438 } +439 +440 /** +441 * Silently closes an output stream ignoring errors. +442 * +443 * @param stream an output stream to close +444 */ +445 private void closeStream(OutputStream stream) { +446 if (stream != null) { +447 try { +448 stream.close(); +449 } catch (IOException ex) { +450 LOGGER.trace("", ex); +451 } +452 } +453 } +454 +455 /** +456 * Sets evidence from the pom on the supplied dependency. +457 * +458 * @param dependency the dependency to set data on +459 * @param pom the information from the pom +460 * @param classes a collection of ClassNameInformation - containing data +461 * about the fully qualified class names within the JAR file being analyzed +462 * @return true if there was evidence within the pom that we could use; +463 * otherwise false +464 */ +465 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { +466 boolean foundSomething = false; +467 boolean addAsIdentifier = true; +468 if (pom == null) { +469 return foundSomething; +470 } +471 String groupid = pom.getGroupId(); +472 String parentGroupId = pom.getParentGroupId(); +473 String artifactid = pom.getArtifactId(); +474 String parentArtifactId = pom.getParentArtifactId(); +475 String version = pom.getVersion(); +476 String parentVersion = pom.getParentVersion(); +477 +478 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { +479 parentGroupId = null; +480 parentArtifactId = null; +481 parentVersion = null; +482 } +483 +484 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { +485 groupid = parentGroupId; +486 } +487 +488 final String originalGroupID = groupid; +489 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { +490 groupid = groupid.substring(4); +491 } +492 +493 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { +494 artifactid = parentArtifactId; +495 } +496 +497 final String originalArtifactID = artifactid; +498 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { +499 artifactid = artifactid.substring(4); +500 } +501 +502 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { +503 version = parentVersion; +504 } +505 +506 if (groupid != null && !groupid.isEmpty()) { +507 foundSomething = true; +508 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); +509 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); +510 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); +511 addMatchingValues(classes, groupid, dependency.getProductEvidence()); +512 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { +513 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); +514 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); +515 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); +516 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); +517 } +518 } else { +519 addAsIdentifier = false; +520 } +521 +522 if (artifactid != null && !artifactid.isEmpty()) { +523 foundSomething = true; +524 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); +525 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); +526 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); +527 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); +528 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { +529 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); +530 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); +531 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); +532 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); +533 } +534 } else { +535 addAsIdentifier = false; +536 } +537 +538 if (version != null && !version.isEmpty()) { +539 foundSomething = true; +540 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); +541 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { +542 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); +543 } +544 } else { +545 addAsIdentifier = false; +546 } +547 +548 if (addAsIdentifier) { +549 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); +550 } +551 +552 // org name +553 final String org = pom.getOrganization(); +554 if (org != null && !org.isEmpty()) { +555 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); +556 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); +557 addMatchingValues(classes, org, dependency.getVendorEvidence()); +558 addMatchingValues(classes, org, dependency.getProductEvidence()); +559 } +560 //pom name +561 final String pomName = pom.getName(); +562 if (pomName +563 != null && !pomName.isEmpty()) { +564 foundSomething = true; +565 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +566 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +567 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); +568 addMatchingValues(classes, pomName, dependency.getProductEvidence()); +569 } +570 +571 //Description +572 final String description = pom.getDescription(); +573 if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { +574 foundSomething = true; +575 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); +576 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); +577 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); +578 } +579 +580 final String projectURL = pom.getProjectURL(); +581 if (projectURL != null && !projectURL.trim().isEmpty()) { +582 dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST); +583 } +584 +585 extractLicense(pom, dependency); +586 return foundSomething; +587 } +588 +589 /** +590 * Analyzes the path information of the classes contained within the +591 * JarAnalyzer to try and determine possible vendor or product names. If any +592 * are found they are stored in the packageVendor and packageProduct +593 * hashSets. +594 * +595 * @param classNames a list of class names +596 * @param dependency a dependency to analyze +597 * @param addPackagesAsEvidence a flag indicating whether or not package +598 * names should be added as evidence. +599 */ +600 protected void analyzePackageNames(List<ClassNameInformation> classNames, +601 Dependency dependency, boolean addPackagesAsEvidence) { +602 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); +603 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); +604 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); +605 +606 final int classCount = classNames.size(); +607 final EvidenceCollection vendor = dependency.getVendorEvidence(); +608 final EvidenceCollection product = dependency.getProductEvidence(); +609 +610 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { +611 final float ratio = entry.getValue() / (float) classCount; +612 if (ratio > 0.5) { +613 //TODO remove weighting +614 vendor.addWeighting(entry.getKey()); +615 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +616 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +617 } +618 } +619 } +620 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { +621 final float ratio = entry.getValue() / (float) classCount; +622 if (ratio > 0.5) { +623 product.addWeighting(entry.getKey()); +624 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +625 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +626 } +627 } +628 } +629 } +630 +631 /** +632 * <p> +633 * Reads the manifest from the JAR file and collects the entries. Some +634 * vendorKey entries are:</p> +635 * <ul><li>Implementation Title</li> +636 * <li>Implementation Version</li> <li>Implementation Vendor</li> +637 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle +638 * Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main +639 * Class</li> </ul> +640 * However, all but a handful of specific entries are read in. +641 * +642 * @param dependency A reference to the dependency +643 * @param classInformation a collection of class information +644 * @return whether evidence was identified parsing the manifest +645 * @throws IOException if there is an issue reading the JAR file +646 */ +647 protected boolean parseManifest(Dependency dependency, +648 List<ClassNameInformation> classInformation) +649 throws IOException { +650 boolean foundSomething = false; +651 JarFile jar = null; +652 try { +653 jar = new JarFile(dependency.getActualFilePath()); +654 final Manifest manifest = jar.getManifest(); +655 if (manifest == null) { +656 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") +657 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") +658 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") +659 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { +660 LOGGER.debug("Jar file '{}' does not contain a manifest.", +661 dependency.getFileName()); +662 } +663 return false; +664 } +665 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); +666 final EvidenceCollection productEvidence = dependency.getProductEvidence(); +667 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); +668 +669 String source = "Manifest"; +670 String specificationVersion = null; +671 boolean hasImplementationVersion = false; +672 Attributes atts = manifest.getMainAttributes(); +673 for (Entry<Object, Object> entry : atts.entrySet()) { +674 String key = entry.getKey().toString(); +675 String value = atts.getValue(key); +676 if (HTML_DETECTION_PATTERN.matcher(value).find()) { +677 value = Jsoup.parse(value).text(); +678 } +679 if (IGNORE_VALUES.contains(value)) { +680 continue; +681 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { +682 foundSomething = true; +683 productEvidence.addEvidence(source, key, value, Confidence.HIGH); +684 addMatchingValues(classInformation, value, productEvidence); +685 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +686 hasImplementationVersion = true; +687 foundSomething = true; +688 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +689 } else if ("specification-version".equalsIgnoreCase(key)) { +690 specificationVersion = key; +691 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { +692 foundSomething = true; +693 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +694 addMatchingValues(classInformation, value, vendorEvidence); +695 } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { +696 foundSomething = true; +697 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +698 addMatchingValues(classInformation, value, vendorEvidence); +699 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { +700 foundSomething = true; +701 addDescription(dependency, value, "manifest", key); +702 addMatchingValues(classInformation, value, productEvidence); +703 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { +704 foundSomething = true; +705 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +706 addMatchingValues(classInformation, value, productEvidence); +707 // //the following caused false positives. +708 // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { +709 // foundSomething = true; +710 // vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +711 // addMatchingValues(classInformation, value, vendorEvidence); +712 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { +713 foundSomething = true; +714 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +715 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { +716 continue; +717 //skipping main class as if this has important information to add +718 // it will be added during class name analysis... if other fields +719 // have the information from the class name then they will get added... +720 } else { +721 key = key.toLowerCase(); +722 if (!IGNORE_KEYS.contains(key) +723 && !key.endsWith("jdk") +724 && !key.contains("lastmodified") +725 && !key.endsWith("package") +726 && !key.endsWith("classpath") +727 && !key.endsWith("class-path") +728 && !key.endsWith("-scm") //todo change this to a regex? +729 && !key.startsWith("scm-") +730 && !value.trim().startsWith("scm:") +731 && !isImportPackage(key, value) +732 && !isPackage(key, value)) { +733 foundSomething = true; +734 if (key.contains("version")) { +735 if (!key.contains("specification")) { +736 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +737 } +738 } else if ("build-id".equals(key)) { +739 int pos = value.indexOf('('); +740 if (pos >= 0) { +741 value = value.substring(0, pos - 1); +742 } +743 pos = value.indexOf('['); +744 if (pos >= 0) { +745 value = value.substring(0, pos - 1); +746 } +747 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +748 } else if (key.contains("title")) { +749 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +750 addMatchingValues(classInformation, value, productEvidence); +751 } else if (key.contains("vendor")) { +752 if (key.contains("specification")) { +753 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); 754 } else { -755 productEvidence.addEvidence(source, key, value, Confidence.LOW); -756 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -757 addMatchingValues(classInformation, value, vendorEvidence); -758 addMatchingValues(classInformation, value, productEvidence); -759 if (value.matches(".*\\d.*")) { -760 final StringTokenizer tokenizer = new StringTokenizer(value, " "); -761 while (tokenizer.hasMoreElements()) { -762 final String s = tokenizer.nextToken(); -763 if (s.matches("^[0-9.]+$")) { -764 versionEvidence.addEvidence(source, key, s, Confidence.LOW); -765 } -766 } -767 } -768 } -769 } -770 } -771 } -772 } -773 -774 final Map<String, Attributes> entries = manifest.getEntries(); -775 for (Iterator<String> it = entries.keySet().iterator(); it.hasNext();) { -776 final String name = it.next(); -777 source = "manifest: " + name; -778 atts = entries.get(name); -779 for (Entry<Object, Object> entry : atts.entrySet()) { -780 final String key = entry.getKey().toString(); -781 final String value = atts.getValue(key); -782 if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { -783 foundSomething = true; -784 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -785 addMatchingValues(classInformation, value, productEvidence); -786 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { -787 foundSomething = true; -788 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -789 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { -790 foundSomething = true; -791 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -792 addMatchingValues(classInformation, value, vendorEvidence); -793 } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) { +755 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +756 addMatchingValues(classInformation, value, vendorEvidence); +757 } +758 } else if (key.contains("name")) { +759 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +760 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +761 addMatchingValues(classInformation, value, vendorEvidence); +762 addMatchingValues(classInformation, value, productEvidence); +763 } else if (key.contains("license")) { +764 addLicense(dependency, value); +765 } else if (key.contains("description")) { +766 addDescription(dependency, value, "manifest", key); +767 } else { +768 productEvidence.addEvidence(source, key, value, Confidence.LOW); +769 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); +770 addMatchingValues(classInformation, value, vendorEvidence); +771 addMatchingValues(classInformation, value, productEvidence); +772 if (value.matches(".*\\d.*")) { +773 final StringTokenizer tokenizer = new StringTokenizer(value, " "); +774 while (tokenizer.hasMoreElements()) { +775 final String s = tokenizer.nextToken(); +776 if (s.matches("^[0-9.]+$")) { +777 versionEvidence.addEvidence(source, key, s, Confidence.LOW); +778 } +779 } +780 } +781 } +782 } +783 } +784 } +785 +786 for (Map.Entry<String, Attributes> item : manifest.getEntries().entrySet()) { +787 final String name = item.getKey(); +788 source = "manifest: " + name; +789 atts = item.getValue(); +790 for (Entry<Object, Object> entry : atts.entrySet()) { +791 final String key = entry.getKey().toString(); +792 final String value = atts.getValue(key); +793 if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { 794 foundSomething = true; 795 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); 796 addMatchingValues(classInformation, value, productEvidence); -797 } -798 } -799 } -800 if (specificationVersion != null && !hasImplementationVersion) { -801 foundSomething = true; -802 versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH); -803 } -804 } finally { -805 if (jar != null) { -806 jar.close(); -807 } -808 } -809 return foundSomething; -810 } -811 -812 /** -813 * Adds a description to the given dependency. If the description contains one of the following strings beyond 100 characters, -814 * then the description used will be trimmed to that position: -815 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses "</li></ul> -816 * -817 * @param dependency a dependency -818 * @param description the description -819 * @param source the source of the evidence -820 * @param key the "name" of the evidence -821 * @return if the description is trimmed, the trimmed version is returned; otherwise the original description is returned -822 */ -823 public static String addDescription(Dependency dependency, String description, String source, String key) { -824 if (dependency.getDescription() == null) { -825 dependency.setDescription(description); -826 } -827 String desc; -828 if (HTML_DETECTION_PATTERN.matcher(description).find()) { -829 desc = Jsoup.parse(description).text(); -830 } else { -831 desc = description; -832 } -833 dependency.setDescription(desc); -834 if (desc.length() > 100) { -835 desc = desc.replaceAll("\\s\\s+", " "); -836 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); -837 final int posLike = desc.toLowerCase().indexOf("like ", 100); -838 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); -839 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); -840 int pos = -1; -841 pos = Math.max(pos, posSuchAs); -842 if (pos >= 0 && posLike >= 0) { -843 pos = Math.min(pos, posLike); -844 } else { -845 pos = Math.max(pos, posLike); -846 } -847 if (pos >= 0 && posWillUse >= 0) { -848 pos = Math.min(pos, posWillUse); -849 } else { -850 pos = Math.max(pos, posWillUse); -851 } -852 if (pos >= 0 && posUses >= 0) { -853 pos = Math.min(pos, posUses); -854 } else { -855 pos = Math.max(pos, posUses); -856 } -857 -858 if (pos > 0) { -859 desc = desc.substring(0, pos) + "..."; +797 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +798 foundSomething = true; +799 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +800 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { +801 foundSomething = true; +802 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +803 addMatchingValues(classInformation, value, vendorEvidence); +804 } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) { +805 foundSomething = true; +806 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +807 addMatchingValues(classInformation, value, productEvidence); +808 } +809 } +810 } +811 if (specificationVersion != null && !hasImplementationVersion) { +812 foundSomething = true; +813 versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH); +814 } +815 } finally { +816 if (jar != null) { +817 jar.close(); +818 } +819 } +820 return foundSomething; +821 } +822 +823 /** +824 * Adds a description to the given dependency. If the description contains +825 * one of the following strings beyond 100 characters, then the description +826 * used will be trimmed to that position: +827 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses +828 * "</li></ul> +829 * +830 * @param dependency a dependency +831 * @param description the description +832 * @param source the source of the evidence +833 * @param key the "name" of the evidence +834 * @return if the description is trimmed, the trimmed version is returned; +835 * otherwise the original description is returned +836 */ +837 public static String addDescription(Dependency dependency, String description, String source, String key) { +838 if (dependency.getDescription() == null) { +839 dependency.setDescription(description); +840 } +841 String desc; +842 if (HTML_DETECTION_PATTERN.matcher(description).find()) { +843 desc = Jsoup.parse(description).text(); +844 } else { +845 desc = description; +846 } +847 dependency.setDescription(desc); +848 if (desc.length() > 100) { +849 desc = desc.replaceAll("\\s\\s+", " "); +850 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); +851 final int posLike = desc.toLowerCase().indexOf("like ", 100); +852 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); +853 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); +854 int pos = -1; +855 pos = Math.max(pos, posSuchAs); +856 if (pos >= 0 && posLike >= 0) { +857 pos = Math.min(pos, posLike); +858 } else { +859 pos = Math.max(pos, posLike); 860 } -861 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); -862 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); -863 } else { -864 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -865 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -866 } -867 return desc; -868 } -869 -870 /** -871 * Adds a license to the given dependency. -872 * -873 * @param d a dependency -874 * @param license the license -875 */ -876 private void addLicense(Dependency d, String license) { -877 if (d.getLicense() == null) { -878 d.setLicense(license); -879 } else if (!d.getLicense().contains(license)) { -880 d.setLicense(d.getLicense() + NEWLINE + license); -881 } +861 if (pos >= 0 && posWillUse >= 0) { +862 pos = Math.min(pos, posWillUse); +863 } else { +864 pos = Math.max(pos, posWillUse); +865 } +866 if (pos >= 0 && posUses >= 0) { +867 pos = Math.min(pos, posUses); +868 } else { +869 pos = Math.max(pos, posUses); +870 } +871 +872 if (pos > 0) { +873 desc = desc.substring(0, pos) + "..."; +874 } +875 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); +876 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); +877 } else { +878 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +879 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +880 } +881 return desc; 882 } 883 884 /** -885 * The parent directory for the individual directories per archive. -886 */ -887 private File tempFileLocation = null; -888 -889 /** -890 * Initializes the JarAnalyzer. -891 * -892 * @throws Exception is thrown if there is an exception creating a temporary directory -893 */ -894 @Override -895 public void initializeFileTypeAnalyzer() throws Exception { -896 final File baseDir = Settings.getTempDirectory(); -897 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -898 if (!tempFileLocation.delete()) { -899 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); -900 throw new AnalysisException(msg); -901 } -902 if (!tempFileLocation.mkdirs()) { -903 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); -904 throw new AnalysisException(msg); -905 } -906 } -907 -908 /** -909 * Deletes any files extracted from the JAR during analysis. -910 */ -911 @Override -912 public void close() { -913 if (tempFileLocation != null && tempFileLocation.exists()) { -914 LOGGER.debug("Attempting to delete temporary files"); -915 final boolean success = FileUtils.delete(tempFileLocation); -916 if (!success) { -917 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); -918 } -919 } -920 } -921 -922 /** -923 * Determines if the key value pair from the manifest is for an "import" type entry for package names. -924 * -925 * @param key the key from the manifest -926 * @param value the value from the manifest -927 * @return true or false depending on if it is believed the entry is an "import" entry -928 */ -929 private boolean isImportPackage(String key, String value) { -930 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); -931 final boolean matches = packageRx.matcher(value).matches(); -932 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); -933 } -934 -935 /** -936 * Cycles through an enumeration of JarEntries, contained within the dependency, and returns a list of the class names. This -937 * does not include core Java package names (i.e. java.* or javax.*). -938 * -939 * @param dependency the dependency being analyzed -940 * @return an list of fully qualified class names -941 */ -942 private List<ClassNameInformation> collectClassNames(Dependency dependency) { -943 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); -944 JarFile jar = null; -945 try { -946 jar = new JarFile(dependency.getActualFilePath()); -947 final Enumeration<JarEntry> entries = jar.entries(); -948 while (entries.hasMoreElements()) { -949 final JarEntry entry = entries.nextElement(); -950 final String name = entry.getName().toLowerCase(); -951 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. -952 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { -953 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); -954 classNames.add(className); -955 } -956 } -957 } catch (IOException ex) { -958 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName()); -959 LOGGER.debug("", ex); -960 } finally { -961 if (jar != null) { -962 try { -963 jar.close(); -964 } catch (IOException ex) { -965 LOGGER.trace("", ex); -966 } -967 } -968 } -969 return classNames; -970 } -971 -972 /** -973 * Cycles through the list of class names and places the package levels 0-3 into the provided maps for vendor and product. -974 * This is helpful when analyzing vendor/product as many times this is included in the package name. -975 * -976 * @param classNames a list of class names -977 * @param vendor HashMap of possible vendor names from package names (e.g. owasp) -978 * @param product HashMap of possible product names from package names (e.g. dependencycheck) -979 */ -980 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, -981 Map<String, Integer> vendor, Map<String, Integer> product) { -982 for (ClassNameInformation entry : classNames) { -983 final List<String> list = entry.getPackageStructure(); -984 addEntry(vendor, list.get(0)); -985 -986 if (list.size() == 2) { -987 addEntry(product, list.get(1)); -988 } -989 if (list.size() == 3) { -990 addEntry(vendor, list.get(1)); -991 addEntry(product, list.get(1)); -992 addEntry(product, list.get(2)); -993 } -994 if (list.size() >= 4) { -995 addEntry(vendor, list.get(1)); -996 addEntry(vendor, list.get(2)); -997 addEntry(product, list.get(1)); -998 addEntry(product, list.get(2)); -999 addEntry(product, list.get(3)); -1000 } -1001 } -1002 } -1003 -1004 /** -1005 * Adds an entry to the specified collection and sets the Integer (e.g. the count) to 1. If the entry already exists in the -1006 * collection then the Integer is incremented by 1. -1007 * -1008 * @param collection a collection of strings and their occurrence count -1009 * @param key the key to add to the collection -1010 */ -1011 private void addEntry(Map<String, Integer> collection, String key) { -1012 if (collection.containsKey(key)) { -1013 collection.put(key, collection.get(key) + 1); -1014 } else { -1015 collection.put(key, 1); -1016 } -1017 } -1018 -1019 /** -1020 * Cycles through the collection of class name information to see if parts of the package names are contained in the provided -1021 * value. If found, it will be added as the HIGHEST confidence evidence because we have more then one source corroborating the -1022 * value. -1023 * -1024 * @param classes a collection of class name information -1025 * @param value the value to check to see if it contains a package name -1026 * @param evidence the evidence collection to add new entries too -1027 */ -1028 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { -1029 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { -1030 return; -1031 } -1032 final String text = value.toLowerCase(); -1033 for (ClassNameInformation cni : classes) { -1034 for (String key : cni.getPackageStructure()) { -1035 final Pattern p = Pattern.compile("\b" + key + "\b"); -1036 if (p.matcher(text).find()) { -1037 //if (text.contains(key)) { //note, package structure elements are already lowercase. -1038 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); -1039 } -1040 } -1041 } -1042 } -1043 -1044 /** -1045 * Simple check to see if the attribute from a manifest is just a package name. -1046 * -1047 * @param key the key of the value to check -1048 * @param value the value to check -1049 * @return true if the value looks like a java package name, otherwise false -1050 */ -1051 private boolean isPackage(String key, String value) { -1052 -1053 return !key.matches(".*(version|title|vendor|name|license|description).*") -1054 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); -1055 -1056 } -1057 -1058 /** -1059 * Extracts the license information from the pom and adds it to the dependency. -1060 * -1061 * @param pom the pom object -1062 * @param dependency the dependency to add license information too -1063 */ -1064 public static void extractLicense(Model pom, Dependency dependency) { -1065 //license -1066 if (pom.getLicenses() != null) { -1067 String license = null; -1068 for (License lic : pom.getLicenses()) { -1069 String tmp = null; -1070 if (lic.getName() != null) { -1071 tmp = lic.getName(); -1072 } -1073 if (lic.getUrl() != null) { -1074 if (tmp == null) { -1075 tmp = lic.getUrl(); -1076 } else { -1077 tmp += ": " + lic.getUrl(); -1078 } -1079 } -1080 if (tmp == null) { -1081 continue; -1082 } -1083 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { -1084 tmp = Jsoup.parse(tmp).text(); -1085 } -1086 if (license == null) { -1087 license = tmp; -1088 } else { -1089 license += "\n" + tmp; -1090 } -1091 } -1092 if (license != null) { -1093 dependency.setLicense(license); -1094 -1095 } -1096 } -1097 } -1098 -1099 /** -1100 * Stores information about a class name. -1101 */ -1102 protected static class ClassNameInformation { -1103 -1104 /** -1105 * <p> -1106 * Stores information about a given class name. This class will keep the fully qualified class name and a list of the -1107 * important parts of the package structure. Up to the first four levels of the package structure are stored, excluding a -1108 * leading "org" or "com". Example:</p> -1109 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); -1110 * System.out.println(obj.getName()); -1111 * for (String p : obj.getPackageStructure()) -1112 * System.out.println(p); -1113 * </code> -1114 * <p> -1115 * Would result in:</p> -1116 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer -1117 * owasp -1118 * dependencycheck -1119 * analyzer -1120 * jaranalyzer</code> -1121 * -1122 * @param className a fully qualified class name -1123 */ -1124 ClassNameInformation(String className) { -1125 name = className; -1126 if (name.contains("/")) { -1127 final String[] tmp = className.toLowerCase().split("/"); -1128 int start = 0; -1129 int end = 3; -1130 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { -1131 start = 1; -1132 end = 4; -1133 } -1134 if (tmp.length <= end) { -1135 end = tmp.length - 1; -1136 } -1137 for (int i = start; i <= end; i++) { -1138 packageStructure.add(tmp[i]); -1139 } -1140 } else { -1141 packageStructure.add(name); -1142 } -1143 } -1144 /** -1145 * The fully qualified class name. -1146 */ -1147 private String name; -1148 -1149 /** -1150 * Get the value of name -1151 * -1152 * @return the value of name -1153 */ -1154 public String getName() { -1155 return name; -1156 } -1157 -1158 /** -1159 * Set the value of name -1160 * -1161 * @param name new value of name -1162 */ -1163 public void setName(String name) { -1164 this.name = name; -1165 } -1166 /** -1167 * Up to the first four levels of the package structure, excluding a leading "org" or "com". -1168 */ -1169 private final ArrayList<String> packageStructure = new ArrayList<String>(); -1170 -1171 /** -1172 * Get the value of packageStructure -1173 * -1174 * @return the value of packageStructure -1175 */ -1176 public ArrayList<String> getPackageStructure() { -1177 return packageStructure; -1178 } -1179 } -1180 -1181 /** -1182 * Retrieves the next temporary directory to extract an archive too. -1183 * -1184 * @return a directory -1185 * @throws AnalysisException thrown if unable to create temporary directory -1186 */ -1187 private File getNextTempDirectory() throws AnalysisException { -1188 dirCount += 1; -1189 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); -1190 //getting an exception for some directories not being able to be created; might be because the directory already exists? -1191 if (directory.exists()) { -1192 return getNextTempDirectory(); +885 * Adds a license to the given dependency. +886 * +887 * @param d a dependency +888 * @param license the license +889 */ +890 private void addLicense(Dependency d, String license) { +891 if (d.getLicense() == null) { +892 d.setLicense(license); +893 } else if (!d.getLicense().contains(license)) { +894 d.setLicense(d.getLicense() + NEWLINE + license); +895 } +896 } +897 +898 /** +899 * The parent directory for the individual directories per archive. +900 */ +901 private File tempFileLocation = null; +902 +903 /** +904 * Initializes the JarAnalyzer. +905 * +906 * @throws Exception is thrown if there is an exception creating a temporary +907 * directory +908 */ +909 @Override +910 public void initializeFileTypeAnalyzer() throws Exception { +911 final File baseDir = Settings.getTempDirectory(); +912 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +913 if (!tempFileLocation.delete()) { +914 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); +915 throw new AnalysisException(msg); +916 } +917 if (!tempFileLocation.mkdirs()) { +918 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); +919 throw new AnalysisException(msg); +920 } +921 } +922 +923 /** +924 * Deletes any files extracted from the JAR during analysis. +925 */ +926 @Override +927 public void close() { +928 if (tempFileLocation != null && tempFileLocation.exists()) { +929 LOGGER.debug("Attempting to delete temporary files"); +930 final boolean success = FileUtils.delete(tempFileLocation); +931 if (!success) { +932 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); +933 } +934 } +935 } +936 +937 /** +938 * Determines if the key value pair from the manifest is for an "import" +939 * type entry for package names. +940 * +941 * @param key the key from the manifest +942 * @param value the value from the manifest +943 * @return true or false depending on if it is believed the entry is an +944 * "import" entry +945 */ +946 private boolean isImportPackage(String key, String value) { +947 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); +948 final boolean matches = packageRx.matcher(value).matches(); +949 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); +950 } +951 +952 /** +953 * Cycles through an enumeration of JarEntries, contained within the +954 * dependency, and returns a list of the class names. This does not include +955 * core Java package names (i.e. java.* or javax.*). +956 * +957 * @param dependency the dependency being analyzed +958 * @return an list of fully qualified class names +959 */ +960 private List<ClassNameInformation> collectClassNames(Dependency dependency) { +961 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); +962 JarFile jar = null; +963 try { +964 jar = new JarFile(dependency.getActualFilePath()); +965 final Enumeration<JarEntry> entries = jar.entries(); +966 while (entries.hasMoreElements()) { +967 final JarEntry entry = entries.nextElement(); +968 final String name = entry.getName().toLowerCase(); +969 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. +970 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { +971 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); +972 classNames.add(className); +973 } +974 } +975 } catch (IOException ex) { +976 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName()); +977 LOGGER.debug("", ex); +978 } finally { +979 if (jar != null) { +980 try { +981 jar.close(); +982 } catch (IOException ex) { +983 LOGGER.trace("", ex); +984 } +985 } +986 } +987 return classNames; +988 } +989 +990 /** +991 * Cycles through the list of class names and places the package levels 0-3 +992 * into the provided maps for vendor and product. This is helpful when +993 * analyzing vendor/product as many times this is included in the package +994 * name. +995 * +996 * @param classNames a list of class names +997 * @param vendor HashMap of possible vendor names from package names (e.g. +998 * owasp) +999 * @param product HashMap of possible product names from package names (e.g. +1000 * dependencycheck) +1001 */ +1002 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, +1003 Map<String, Integer> vendor, Map<String, Integer> product) { +1004 for (ClassNameInformation entry : classNames) { +1005 final List<String> list = entry.getPackageStructure(); +1006 addEntry(vendor, list.get(0)); +1007 +1008 if (list.size() == 2) { +1009 addEntry(product, list.get(1)); +1010 } +1011 if (list.size() == 3) { +1012 addEntry(vendor, list.get(1)); +1013 addEntry(product, list.get(1)); +1014 addEntry(product, list.get(2)); +1015 } +1016 if (list.size() >= 4) { +1017 addEntry(vendor, list.get(1)); +1018 addEntry(vendor, list.get(2)); +1019 addEntry(product, list.get(1)); +1020 addEntry(product, list.get(2)); +1021 addEntry(product, list.get(3)); +1022 } +1023 } +1024 } +1025 +1026 /** +1027 * Adds an entry to the specified collection and sets the Integer (e.g. the +1028 * count) to 1. If the entry already exists in the collection then the +1029 * Integer is incremented by 1. +1030 * +1031 * @param collection a collection of strings and their occurrence count +1032 * @param key the key to add to the collection +1033 */ +1034 private void addEntry(Map<String, Integer> collection, String key) { +1035 if (collection.containsKey(key)) { +1036 collection.put(key, collection.get(key) + 1); +1037 } else { +1038 collection.put(key, 1); +1039 } +1040 } +1041 +1042 /** +1043 * Cycles through the collection of class name information to see if parts +1044 * of the package names are contained in the provided value. If found, it +1045 * will be added as the HIGHEST confidence evidence because we have more +1046 * then one source corroborating the value. +1047 * +1048 * @param classes a collection of class name information +1049 * @param value the value to check to see if it contains a package name +1050 * @param evidence the evidence collection to add new entries too +1051 */ +1052 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { +1053 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { +1054 return; +1055 } +1056 final String text = value.toLowerCase(); +1057 for (ClassNameInformation cni : classes) { +1058 for (String key : cni.getPackageStructure()) { +1059 final Pattern p = Pattern.compile("\b" + key + "\b"); +1060 if (p.matcher(text).find()) { +1061 //if (text.contains(key)) { //note, package structure elements are already lowercase. +1062 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); +1063 } +1064 } +1065 } +1066 } +1067 +1068 /** +1069 * Simple check to see if the attribute from a manifest is just a package +1070 * name. +1071 * +1072 * @param key the key of the value to check +1073 * @param value the value to check +1074 * @return true if the value looks like a java package name, otherwise false +1075 */ +1076 private boolean isPackage(String key, String value) { +1077 +1078 return !key.matches(".*(version|title|vendor|name|license|description).*") +1079 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); +1080 +1081 } +1082 +1083 /** +1084 * Extracts the license information from the pom and adds it to the +1085 * dependency. +1086 * +1087 * @param pom the pom object +1088 * @param dependency the dependency to add license information too +1089 */ +1090 public static void extractLicense(Model pom, Dependency dependency) { +1091 //license +1092 if (pom.getLicenses() != null) { +1093 String license = null; +1094 for (License lic : pom.getLicenses()) { +1095 String tmp = null; +1096 if (lic.getName() != null) { +1097 tmp = lic.getName(); +1098 } +1099 if (lic.getUrl() != null) { +1100 if (tmp == null) { +1101 tmp = lic.getUrl(); +1102 } else { +1103 tmp += ": " + lic.getUrl(); +1104 } +1105 } +1106 if (tmp == null) { +1107 continue; +1108 } +1109 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { +1110 tmp = Jsoup.parse(tmp).text(); +1111 } +1112 if (license == null) { +1113 license = tmp; +1114 } else { +1115 license += "\n" + tmp; +1116 } +1117 } +1118 if (license != null) { +1119 dependency.setLicense(license); +1120 +1121 } +1122 } +1123 } +1124 +1125 /** +1126 * Stores information about a class name. +1127 */ +1128 protected static class ClassNameInformation { +1129 +1130 /** +1131 * <p> +1132 * Stores information about a given class name. This class will keep the +1133 * fully qualified class name and a list of the important parts of the +1134 * package structure. Up to the first four levels of the package +1135 * structure are stored, excluding a leading "org" or "com". +1136 * Example:</p> +1137 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); +1138 * System.out.println(obj.getName()); +1139 * for (String p : obj.getPackageStructure()) +1140 * System.out.println(p); +1141 * </code> +1142 * <p> +1143 * Would result in:</p> +1144 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer +1145 * owasp +1146 * dependencycheck +1147 * analyzer +1148 * jaranalyzer</code> +1149 * +1150 * @param className a fully qualified class name +1151 */ +1152 ClassNameInformation(String className) { +1153 name = className; +1154 if (name.contains("/")) { +1155 final String[] tmp = className.toLowerCase().split("/"); +1156 int start = 0; +1157 int end = 3; +1158 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { +1159 start = 1; +1160 end = 4; +1161 } +1162 if (tmp.length <= end) { +1163 end = tmp.length - 1; +1164 } +1165 for (int i = start; i <= end; i++) { +1166 packageStructure.add(tmp[i]); +1167 } +1168 } else { +1169 packageStructure.add(name); +1170 } +1171 } +1172 /** +1173 * The fully qualified class name. +1174 */ +1175 private String name; +1176 +1177 /** +1178 * Get the value of name +1179 * +1180 * @return the value of name +1181 */ +1182 public String getName() { +1183 return name; +1184 } +1185 +1186 /** +1187 * Set the value of name +1188 * +1189 * @param name new value of name +1190 */ +1191 public void setName(String name) { +1192 this.name = name; 1193 } -1194 if (!directory.mkdirs()) { -1195 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); -1196 throw new AnalysisException(msg); -1197 } -1198 return directory; -1199 } -1200 } +1194 /** +1195 * Up to the first four levels of the package structure, excluding a +1196 * leading "org" or "com". +1197 */ +1198 private final ArrayList<String> packageStructure = new ArrayList<String>(); +1199 +1200 /** +1201 * Get the value of packageStructure +1202 * +1203 * @return the value of packageStructure +1204 */ +1205 public ArrayList<String> getPackageStructure() { +1206 return packageStructure; +1207 } +1208 } +1209 +1210 /** +1211 * Retrieves the next temporary directory to extract an archive too. +1212 * +1213 * @return a directory +1214 * @throws AnalysisException thrown if unable to create temporary directory +1215 */ +1216 private File getNextTempDirectory() throws AnalysisException { +1217 dirCount += 1; +1218 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); +1219 //getting an exception for some directories not being able to be created; might be because the directory already exists? +1220 if (directory.exists()) { +1221 return getNextTempDirectory(); +1222 } +1223 if (!directory.mkdirs()) { +1224 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); +1225 throw new AnalysisException(msg); +1226 } +1227 return directory; +1228 } +1229 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html index bdc2382a5..ebd893860 100644 --- a/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html @@ -53,146 +53,147 @@ 45 * 46 * @author Dale Visser 47 */ -48 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { -49 -50 /** -51 * The logger. -52 */ -53 private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class); -54 -55 /** -56 * The name of the analyzer. -57 */ -58 private static final String ANALYZER_NAME = "Node.js Package Analyzer"; -59 -60 /** -61 * The phase that this analyzer is intended to run in. -62 */ -63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -64 -65 /** -66 * The file name to scan. -67 */ -68 public static final String PACKAGE_JSON = "package.json"; -69 /** -70 * Filter that detects files named "package.json". -71 */ -72 private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance() -73 .addFilenames(PACKAGE_JSON).build(); -74 -75 /** -76 * Returns the FileFilter -77 * -78 * @return the FileFilter -79 */ -80 @Override -81 protected FileFilter getFileFilter() { -82 return PACKAGE_JSON_FILTER; -83 } -84 -85 @Override -86 protected void initializeFileTypeAnalyzer() throws Exception { -87 // NO-OP -88 } -89 -90 /** -91 * Returns the name of the analyzer. -92 * -93 * @return the name of the analyzer. -94 */ -95 @Override -96 public String getName() { -97 return ANALYZER_NAME; -98 } -99 -100 /** -101 * Returns the phase that the analyzer is intended to run in. -102 * -103 * @return the phase that the analyzer is intended to run in. -104 */ -105 @Override -106 public AnalysisPhase getAnalysisPhase() { -107 return ANALYSIS_PHASE; -108 } -109 -110 /** -111 * Returns the key used in the properties file to reference the analyzer's enabled property. -112 * -113 * @return the analyzer's enabled property setting key -114 */ -115 @Override -116 protected String getAnalyzerEnabledSettingKey() { -117 return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED; -118 } -119 -120 @Override -121 protected void analyzeFileType(Dependency dependency, Engine engine) -122 throws AnalysisException { -123 final File file = dependency.getActualFile(); -124 JsonReader jsonReader; -125 try { -126 jsonReader = Json.createReader(FileUtils.openInputStream(file)); -127 } catch (IOException e) { -128 throw new AnalysisException( -129 "Problem occurred while reading dependency file.", e); -130 } -131 try { -132 final JsonObject json = jsonReader.readObject(); -133 final EvidenceCollection productEvidence = dependency.getProductEvidence(); -134 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); -135 if (json.containsKey("name")) { -136 final Object value = json.get("name"); -137 if (value instanceof JsonString) { -138 final String valueString = ((JsonString) value).getString(); -139 productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST); -140 vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW); -141 } else { -142 LOGGER.warn("JSON value not string as expected: {}", value); -143 } -144 } -145 addToEvidence(json, productEvidence, "description"); -146 addToEvidence(json, vendorEvidence, "author"); -147 addToEvidence(json, dependency.getVersionEvidence(), "version"); -148 dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName())); -149 } catch (JsonException e) { -150 LOGGER.warn("Failed to parse package.json file.", e); -151 } finally { -152 jsonReader.close(); -153 } -154 } -155 -156 /** -157 * Adds information to an evidence collection from the node json configuration. -158 * -159 * @param json information from node.js -160 * @param collection a set of evidence about a dependency -161 * @param key the key to obtain the data from the json information -162 */ -163 private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) { -164 if (json.containsKey(key)) { -165 final JsonValue value = json.get(key); -166 if (value instanceof JsonString) { -167 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST); -168 } else if (value instanceof JsonObject) { -169 final JsonObject jsonObject = (JsonObject) value; -170 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) { -171 final String property = entry.getKey(); -172 final JsonValue subValue = entry.getValue(); -173 if (subValue instanceof JsonString) { -174 collection.addEvidence(PACKAGE_JSON, -175 String.format("%s.%s", key, property), -176 ((JsonString) subValue).getString(), -177 Confidence.HIGHEST); -178 } else { -179 LOGGER.warn("JSON sub-value not string as expected: {}", subValue); -180 } -181 } -182 } else { -183 LOGGER.warn("JSON value not string or JSON object as expected: {}", value); -184 } -185 } -186 } -187 } +48 @Experimental +49 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { +50 +51 /** +52 * The logger. +53 */ +54 private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class); +55 +56 /** +57 * The name of the analyzer. +58 */ +59 private static final String ANALYZER_NAME = "Node.js Package Analyzer"; +60 +61 /** +62 * The phase that this analyzer is intended to run in. +63 */ +64 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +65 +66 /** +67 * The file name to scan. +68 */ +69 public static final String PACKAGE_JSON = "package.json"; +70 /** +71 * Filter that detects files named "package.json". +72 */ +73 private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance() +74 .addFilenames(PACKAGE_JSON).build(); +75 +76 /** +77 * Returns the FileFilter +78 * +79 * @return the FileFilter +80 */ +81 @Override +82 protected FileFilter getFileFilter() { +83 return PACKAGE_JSON_FILTER; +84 } +85 +86 @Override +87 protected void initializeFileTypeAnalyzer() throws Exception { +88 // NO-OP +89 } +90 +91 /** +92 * Returns the name of the analyzer. +93 * +94 * @return the name of the analyzer. +95 */ +96 @Override +97 public String getName() { +98 return ANALYZER_NAME; +99 } +100 +101 /** +102 * Returns the phase that the analyzer is intended to run in. +103 * +104 * @return the phase that the analyzer is intended to run in. +105 */ +106 @Override +107 public AnalysisPhase getAnalysisPhase() { +108 return ANALYSIS_PHASE; +109 } +110 +111 /** +112 * Returns the key used in the properties file to reference the analyzer's enabled property. +113 * +114 * @return the analyzer's enabled property setting key +115 */ +116 @Override +117 protected String getAnalyzerEnabledSettingKey() { +118 return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED; +119 } +120 +121 @Override +122 protected void analyzeFileType(Dependency dependency, Engine engine) +123 throws AnalysisException { +124 final File file = dependency.getActualFile(); +125 JsonReader jsonReader; +126 try { +127 jsonReader = Json.createReader(FileUtils.openInputStream(file)); +128 } catch (IOException e) { +129 throw new AnalysisException( +130 "Problem occurred while reading dependency file.", e); +131 } +132 try { +133 final JsonObject json = jsonReader.readObject(); +134 final EvidenceCollection productEvidence = dependency.getProductEvidence(); +135 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); +136 if (json.containsKey("name")) { +137 final Object value = json.get("name"); +138 if (value instanceof JsonString) { +139 final String valueString = ((JsonString) value).getString(); +140 productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST); +141 vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW); +142 } else { +143 LOGGER.warn("JSON value not string as expected: {}", value); +144 } +145 } +146 addToEvidence(json, productEvidence, "description"); +147 addToEvidence(json, vendorEvidence, "author"); +148 addToEvidence(json, dependency.getVersionEvidence(), "version"); +149 dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName())); +150 } catch (JsonException e) { +151 LOGGER.warn("Failed to parse package.json file.", e); +152 } finally { +153 jsonReader.close(); +154 } +155 } +156 +157 /** +158 * Adds information to an evidence collection from the node json configuration. +159 * +160 * @param json information from node.js +161 * @param collection a set of evidence about a dependency +162 * @param key the key to obtain the data from the json information +163 */ +164 private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) { +165 if (json.containsKey(key)) { +166 final JsonValue value = json.get(key); +167 if (value instanceof JsonString) { +168 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST); +169 } else if (value instanceof JsonObject) { +170 final JsonObject jsonObject = (JsonObject) value; +171 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) { +172 final String property = entry.getKey(); +173 final JsonValue subValue = entry.getValue(); +174 if (subValue instanceof JsonString) { +175 collection.addEvidence(PACKAGE_JSON, +176 String.format("%s.%s", key, property), +177 ((JsonString) subValue).getString(), +178 Confidence.HIGHEST); +179 } else { +180 LOGGER.warn("JSON sub-value not string as expected: {}", subValue); +181 } +182 } +183 } else { +184 LOGGER.warn("JSON value not string or JSON object as expected: {}", value); +185 } +186 } +187 } +188 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html index 180509d73..e59ace550 100644 --- a/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html @@ -36,151 +36,189 @@ 28 import java.io.File; 29 import java.io.FileFilter; 30 import java.io.IOException; -31 import java.util.regex.Matcher; -32 import java.util.regex.Pattern; -33 -34 /** -35 * Used to analyze OpenSSL source code present in the file system. -36 * -37 * @author Dale Visser -38 */ -39 public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { -40 -41 private static final int HEXADECIMAL = 16; +31 import java.nio.charset.Charset; +32 import java.util.regex.Matcher; +33 import java.util.regex.Pattern; +34 +35 /** +36 * Used to analyze OpenSSL source code present in the file system. +37 * +38 * @author Dale Visser +39 */ +40 public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { +41 42 /** -43 * Filename to analyze. All other .h files get removed from consideration. +43 * Hexadecimal. 44 */ -45 private static final String OPENSSLV_H = "opensslv.h"; -46 -47 /** -48 * Filter that detects files named "__init__.py". -49 */ -50 private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build(); -51 private static final Pattern VERSION_PATTERN = Pattern.compile( -52 "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL -53 | Pattern.CASE_INSENSITIVE); -54 private static final int MAJOR_OFFSET = 28; -55 private static final long MINOR_MASK = 0x0ff00000L; -56 private static final int MINOR_OFFSET = 20; -57 private static final long FIX_MASK = 0x000ff000L; -58 private static final int FIX_OFFSET = 12; -59 private static final long PATCH_MASK = 0x00000ff0L; -60 private static final int PATCH_OFFSET = 4; -61 private static final int NUM_LETTERS = 26; -62 private static final int STATUS_MASK = 0x0000000f; -63 -64 /** -65 * Returns the open SSL version as a string. -66 * -67 * @param openSSLVersionConstant The open SSL version -68 * @return the version of openssl -69 */ -70 static String getOpenSSLVersion(long openSSLVersionConstant) { -71 final long major = openSSLVersionConstant >>> MAJOR_OFFSET; -72 final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET; -73 final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET; -74 final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET; -75 final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1)); -76 final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK); -77 final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode); -78 return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status); -79 } -80 +45 private static final int HEXADECIMAL = 16; +46 /** +47 * Filename to analyze. All other .h files get removed from consideration. +48 */ +49 private static final String OPENSSLV_H = "opensslv.h"; +50 +51 /** +52 * Filter that detects files named "__init__.py". +53 */ +54 private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build(); +55 /** +56 * Open SSL Version number pattern. +57 */ +58 private static final Pattern VERSION_PATTERN = Pattern.compile( +59 "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL +60 | Pattern.CASE_INSENSITIVE); +61 /** +62 * The offset of the major version number. +63 */ +64 private static final int MAJOR_OFFSET = 28; +65 /** +66 * The mask for the minor version number. +67 */ +68 private static final long MINOR_MASK = 0x0ff00000L; +69 /** +70 * The offset of the minor version number. +71 */ +72 private static final int MINOR_OFFSET = 20; +73 /** +74 * The max for the fix version. +75 */ +76 private static final long FIX_MASK = 0x000ff000L; +77 /** +78 * The offset for the fix version. +79 */ +80 private static final int FIX_OFFSET = 12; 81 /** -82 * Returns the name of the Python Package Analyzer. -83 * -84 * @return the name of the analyzer -85 */ -86 @Override -87 public String getName() { -88 return "OpenSSL Source Analyzer"; -89 } -90 -91 /** -92 * Tell that we are used for information collection. -93 * -94 * @return INFORMATION_COLLECTION +82 * The mask for the patch version. +83 */ +84 private static final long PATCH_MASK = 0x00000ff0L; +85 /** +86 * The offset for the patch version. +87 */ +88 private static final int PATCH_OFFSET = 4; +89 /** +90 * Number of letters. +91 */ +92 private static final int NUM_LETTERS = 26; +93 /** +94 * The status mask. 95 */ -96 @Override -97 public AnalysisPhase getAnalysisPhase() { -98 return AnalysisPhase.INFORMATION_COLLECTION; -99 } -100 -101 /** -102 * Returns the set of supported file extensions. -103 * -104 * @return the set of supported file extensions -105 */ -106 @Override -107 protected FileFilter getFileFilter() { -108 return OPENSSLV_FILTER; -109 } -110 -111 /** -112 * No-op initializer implementation. -113 * -114 * @throws Exception never thrown -115 */ -116 @Override -117 protected void initializeFileTypeAnalyzer() throws Exception { -118 // Nothing to do here. -119 } -120 -121 /** -122 * Analyzes python packages and adds evidence to the dependency. -123 * -124 * @param dependency the dependency being analyzed -125 * @param engine the engine being used to perform the scan -126 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency -127 */ -128 @Override -129 protected void analyzeFileType(Dependency dependency, Engine engine) -130 throws AnalysisException { -131 final File file = dependency.getActualFile(); -132 final String parentName = file.getParentFile().getName(); -133 boolean found = false; -134 final String contents = getFileContents(file); -135 if (!contents.isEmpty()) { -136 final Matcher matcher = VERSION_PATTERN.matcher(contents); -137 if (matcher.find()) { -138 dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant", -139 getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH); -140 found = true; -141 } -142 } -143 if (found) { -144 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H); -145 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST); -146 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST); -147 } else { -148 engine.getDependencies().remove(dependency); -149 } -150 } -151 -152 /** -153 * Retrieves the contents of a given file. -154 * -155 * @param actualFile the file to read -156 * @return the contents of the file -157 * @throws AnalysisException thrown if there is an IO Exception -158 */ -159 private String getFileContents(final File actualFile) -160 throws AnalysisException { -161 String contents; -162 try { -163 contents = FileUtils.readFileToString(actualFile).trim(); -164 } catch (IOException e) { -165 throw new AnalysisException( -166 "Problem occurred while reading dependency file.", e); -167 } -168 return contents; -169 } -170 -171 @Override -172 protected String getAnalyzerEnabledSettingKey() { -173 return Settings.KEYS.ANALYZER_OPENSSL_ENABLED; -174 } -175 } +96 private static final int STATUS_MASK = 0x0000000f; +97 +98 /** +99 * Returns the open SSL version as a string. +100 * +101 * @param openSSLVersionConstant The open SSL version +102 * @return the version of openssl +103 */ +104 static String getOpenSSLVersion(long openSSLVersionConstant) { +105 final long major = openSSLVersionConstant >>> MAJOR_OFFSET; +106 final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET; +107 final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET; +108 final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET; +109 final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1)); +110 final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK); +111 final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode); +112 return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status); +113 } +114 +115 /** +116 * Returns the name of the Python Package Analyzer. +117 * +118 * @return the name of the analyzer +119 */ +120 @Override +121 public String getName() { +122 return "OpenSSL Source Analyzer"; +123 } +124 +125 /** +126 * Tell that we are used for information collection. +127 * +128 * @return INFORMATION_COLLECTION +129 */ +130 @Override +131 public AnalysisPhase getAnalysisPhase() { +132 return AnalysisPhase.INFORMATION_COLLECTION; +133 } +134 +135 /** +136 * Returns the set of supported file extensions. +137 * +138 * @return the set of supported file extensions +139 */ +140 @Override +141 protected FileFilter getFileFilter() { +142 return OPENSSLV_FILTER; +143 } +144 +145 /** +146 * No-op initializer implementation. +147 * +148 * @throws Exception never thrown +149 */ +150 @Override +151 protected void initializeFileTypeAnalyzer() throws Exception { +152 // Nothing to do here. +153 } +154 +155 /** +156 * Analyzes python packages and adds evidence to the dependency. +157 * +158 * @param dependency the dependency being analyzed +159 * @param engine the engine being used to perform the scan +160 * @throws AnalysisException thrown if there is an unrecoverable error +161 * analyzing the dependency +162 */ +163 @Override +164 protected void analyzeFileType(Dependency dependency, Engine engine) +165 throws AnalysisException { +166 final File file = dependency.getActualFile(); +167 final String parentName = file.getParentFile().getName(); +168 boolean found = false; +169 final String contents = getFileContents(file); +170 if (!contents.isEmpty()) { +171 final Matcher matcher = VERSION_PATTERN.matcher(contents); +172 if (matcher.find()) { +173 dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant", +174 getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH); +175 found = true; +176 } +177 } +178 if (found) { +179 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H); +180 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST); +181 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST); +182 } else { +183 engine.getDependencies().remove(dependency); +184 } +185 } +186 +187 /** +188 * Retrieves the contents of a given file. +189 * +190 * @param actualFile the file to read +191 * @return the contents of the file +192 * @throws AnalysisException thrown if there is an IO Exception +193 */ +194 private String getFileContents(final File actualFile) +195 throws AnalysisException { +196 try { +197 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); +198 } catch (IOException e) { +199 throw new AnalysisException( +200 "Problem occurred while reading dependency file.", e); +201 } +202 } +203 +204 /** +205 * Returns the setting for the analyzer enabled setting key. +206 * +207 * @return the setting for the analyzer enabled setting key +208 */ +209 @Override +210 protected String getAnalyzerEnabledSettingKey() { +211 return Settings.KEYS.ANALYZER_OPENSSL_ENABLED; +212 } +213 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html index b7de77c88..0259a9aa0 100644 --- a/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html @@ -58,328 +58,329 @@ 50 * 51 * @author Dale Visser 52 */ -53 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { -54 -55 /** -56 * Name of egg metadata files to analyze. -57 */ -58 private static final String PKG_INFO = "PKG-INFO"; -59 -60 /** -61 * Name of wheel metadata files to analyze. -62 */ -63 private static final String METADATA = "METADATA"; -64 -65 /** -66 * The logger. -67 */ -68 private static final Logger LOGGER = LoggerFactory -69 .getLogger(PythonDistributionAnalyzer.class); -70 -71 /** -72 * The count of directories created during analysis. This is used for creating temporary directories. -73 */ -74 private static int dirCount = 0; -75 -76 /** -77 * The name of the analyzer. -78 */ -79 private static final String ANALYZER_NAME = "Python Distribution Analyzer"; -80 /** -81 * The phase that this analyzer is intended to run in. -82 */ -83 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -84 -85 /** -86 * The set of file extensions supported by this analyzer. -87 */ -88 private static final String[] EXTENSIONS = {"whl", "egg", "zip"}; -89 -90 /** -91 * Used to match on egg archive candidate extensions. -92 */ -93 private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build(); -94 -95 /** -96 * Used to detect files with a .whl extension. -97 */ -98 private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build(); -99 -100 /** -101 * The parent directory for the individual directories per archive. -102 */ -103 private File tempFileLocation; -104 -105 /** -106 * Filter that detects *.dist-info files (but doesn't verify they are directories. -107 */ -108 private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( -109 ".dist-info"); -110 -111 /** -112 * Filter that detects files named "METADATA". -113 */ -114 private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( -115 "EGG-INFO"); -116 -117 /** -118 * Filter that detects files named "METADATA". -119 */ -120 private static final NameFileFilter METADATA_FILTER = new NameFileFilter( -121 METADATA); -122 -123 /** -124 * Filter that detects files named "PKG-INFO". -125 */ -126 private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter( -127 PKG_INFO); -128 -129 /** -130 * The file filter used to determine which files this analyzer supports. -131 */ -132 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters( -133 METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build(); -134 -135 /** -136 * Returns the FileFilter -137 * -138 * @return the FileFilter -139 */ -140 @Override -141 protected FileFilter getFileFilter() { -142 return FILTER; -143 } -144 -145 /** -146 * Returns the name of the analyzer. -147 * -148 * @return the name of the analyzer. -149 */ -150 @Override -151 public String getName() { -152 return ANALYZER_NAME; -153 } -154 -155 /** -156 * Returns the phase that the analyzer is intended to run in. -157 * -158 * @return the phase that the analyzer is intended to run in. -159 */ -160 @Override -161 public AnalysisPhase getAnalysisPhase() { -162 return ANALYSIS_PHASE; -163 } -164 -165 /** -166 * Returns the key used in the properties file to reference the analyzer's enabled property. -167 * -168 * @return the analyzer's enabled property setting key -169 */ -170 @Override -171 protected String getAnalyzerEnabledSettingKey() { -172 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; -173 } -174 -175 @Override -176 protected void analyzeFileType(Dependency dependency, Engine engine) -177 throws AnalysisException { -178 final File actualFile = dependency.getActualFile(); -179 if (WHL_FILTER.accept(actualFile)) { -180 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, -181 METADATA_FILTER); -182 } else if (EGG_OR_ZIP.accept(actualFile)) { -183 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, -184 PKG_INFO_FILTER); -185 } else { -186 final String name = actualFile.getName(); -187 final boolean metadata = METADATA.equals(name); -188 if (metadata || PKG_INFO.equals(name)) { -189 final File parent = actualFile.getParentFile(); -190 final String parentName = parent.getName(); -191 dependency.setDisplayFileName(parentName + "/" + name); -192 if (parent.isDirectory() -193 && (metadata && parentName.endsWith(".dist-info") -194 || parentName.endsWith(".egg-info") || "EGG-INFO" -195 .equals(parentName))) { -196 collectWheelMetadata(dependency, actualFile); -197 } -198 } -199 } -200 } -201 -202 /** -203 * Collects the meta data from an archive. -204 * -205 * @param dependency the archive being scanned -206 * @param folderFilter the filter to apply to the folder -207 * @param metadataFilter the filter to apply to the meta data -208 * @throws AnalysisException thrown when there is a problem analyzing the dependency -209 */ -210 private void collectMetadataFromArchiveFormat(Dependency dependency, -211 FilenameFilter folderFilter, FilenameFilter metadataFilter) -212 throws AnalysisException { -213 final File temp = getNextTempDirectory(); -214 LOGGER.debug("{} exists? {}", temp, temp.exists()); -215 try { -216 ExtractionUtil.extractFilesUsingFilter( -217 new File(dependency.getActualFilePath()), temp, -218 metadataFilter); -219 } catch (ExtractionException ex) { -220 throw new AnalysisException(ex); -221 } -222 -223 collectWheelMetadata( -224 dependency, -225 getMatchingFile(getMatchingFile(temp, folderFilter), -226 metadataFilter)); -227 } -228 -229 /** -230 * Makes sure a usable temporary directory is available. -231 * -232 * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created -233 */ -234 @Override -235 protected void initializeFileTypeAnalyzer() throws Exception { -236 final File baseDir = Settings.getTempDirectory(); -237 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -238 if (!tempFileLocation.delete()) { -239 final String msg = String.format( -240 "Unable to delete temporary file '%s'.", -241 tempFileLocation.getAbsolutePath()); -242 throw new AnalysisException(msg); -243 } -244 if (!tempFileLocation.mkdirs()) { -245 final String msg = String.format( -246 "Unable to create directory '%s'.", -247 tempFileLocation.getAbsolutePath()); -248 throw new AnalysisException(msg); -249 } -250 } -251 -252 /** -253 * Deletes any files extracted from the Wheel during analysis. -254 */ -255 @Override -256 public void close() { -257 if (tempFileLocation != null && tempFileLocation.exists()) { -258 LOGGER.debug("Attempting to delete temporary files"); -259 final boolean success = FileUtils.delete(tempFileLocation); -260 if (!success) { -261 LOGGER.warn( -262 "Failed to delete some temporary files, see the log for more details"); -263 } -264 } -265 } -266 -267 /** -268 * Gathers evidence from the METADATA file. -269 * -270 * @param dependency the dependency being analyzed -271 * @param file a reference to the manifest/properties file -272 */ -273 private static void collectWheelMetadata(Dependency dependency, File file) { -274 final InternetHeaders headers = getManifestProperties(file); -275 addPropertyToEvidence(headers, dependency.getVersionEvidence(), -276 "Version", Confidence.HIGHEST); -277 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", -278 Confidence.HIGHEST); -279 final String url = headers.getHeader("Home-page", null); -280 final EvidenceCollection vendorEvidence = dependency -281 .getVendorEvidence(); -282 if (StringUtils.isNotBlank(url)) { -283 if (UrlStringUtils.isUrl(url)) { -284 vendorEvidence.addEvidence(METADATA, "vendor", url, -285 Confidence.MEDIUM); -286 } -287 } -288 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); -289 final String summary = headers.getHeader("Summary", null); -290 if (StringUtils.isNotBlank(summary)) { -291 JarAnalyzer -292 .addDescription(dependency, summary, METADATA, "summary"); -293 } -294 } -295 -296 /** -297 * Adds a value to the evidence collection. -298 * -299 * @param headers the properties collection -300 * @param evidence the evidence collection to add the value -301 * @param property the property name -302 * @param confidence the confidence of the evidence -303 */ -304 private static void addPropertyToEvidence(InternetHeaders headers, -305 EvidenceCollection evidence, String property, Confidence confidence) { -306 final String value = headers.getHeader(property, null); -307 LOGGER.debug("Property: {}, Value: {}", property, value); -308 if (StringUtils.isNotBlank(value)) { -309 evidence.addEvidence(METADATA, property, value, confidence); -310 } -311 } -312 -313 /** -314 * Returns a list of files that match the given filter, this does not recursively scan the directory. -315 * -316 * @param folder the folder to filter -317 * @param filter the filter to apply to the files in the directory -318 * @return the list of Files in the directory that match the provided filter -319 */ -320 private static File getMatchingFile(File folder, FilenameFilter filter) { -321 File result = null; -322 final File[] matches = folder.listFiles(filter); -323 if (null != matches && 1 == matches.length) { -324 result = matches[0]; -325 } -326 return result; -327 } -328 -329 /** -330 * Reads the manifest entries from the provided file. -331 * -332 * @param manifest the manifest -333 * @return the manifest entries -334 */ -335 private static InternetHeaders getManifestProperties(File manifest) { -336 final InternetHeaders result = new InternetHeaders(); -337 if (null == manifest) { -338 LOGGER.debug("Manifest file not found."); -339 } else { -340 try { -341 result.load(new AutoCloseInputStream(new BufferedInputStream( -342 new FileInputStream(manifest)))); -343 } catch (MessagingException e) { -344 LOGGER.warn(e.getMessage(), e); -345 } catch (FileNotFoundException e) { -346 LOGGER.warn(e.getMessage(), e); -347 } -348 } -349 return result; -350 } -351 -352 /** -353 * Retrieves the next temporary destination directory for extracting an archive. -354 * -355 * @return a directory -356 * @throws AnalysisException thrown if unable to create temporary directory -357 */ -358 private File getNextTempDirectory() throws AnalysisException { -359 File directory; -360 -361 // getting an exception for some directories not being able to be -362 // created; might be because the directory already exists? -363 do { -364 dirCount += 1; -365 directory = new File(tempFileLocation, String.valueOf(dirCount)); -366 } while (directory.exists()); -367 if (!directory.mkdirs()) { -368 throw new AnalysisException(String.format( -369 "Unable to create temp directory '%s'.", -370 directory.getAbsolutePath())); -371 } -372 return directory; -373 } -374 } +53 @Experimental +54 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { +55 +56 /** +57 * Name of egg metadata files to analyze. +58 */ +59 private static final String PKG_INFO = "PKG-INFO"; +60 +61 /** +62 * Name of wheel metadata files to analyze. +63 */ +64 private static final String METADATA = "METADATA"; +65 +66 /** +67 * The logger. +68 */ +69 private static final Logger LOGGER = LoggerFactory +70 .getLogger(PythonDistributionAnalyzer.class); +71 +72 /** +73 * The count of directories created during analysis. This is used for creating temporary directories. +74 */ +75 private static int dirCount = 0; +76 +77 /** +78 * The name of the analyzer. +79 */ +80 private static final String ANALYZER_NAME = "Python Distribution Analyzer"; +81 /** +82 * The phase that this analyzer is intended to run in. +83 */ +84 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +85 +86 /** +87 * The set of file extensions supported by this analyzer. +88 */ +89 private static final String[] EXTENSIONS = {"whl", "egg", "zip"}; +90 +91 /** +92 * Used to match on egg archive candidate extensions. +93 */ +94 private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build(); +95 +96 /** +97 * Used to detect files with a .whl extension. +98 */ +99 private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build(); +100 +101 /** +102 * The parent directory for the individual directories per archive. +103 */ +104 private File tempFileLocation; +105 +106 /** +107 * Filter that detects *.dist-info files (but doesn't verify they are directories. +108 */ +109 private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( +110 ".dist-info"); +111 +112 /** +113 * Filter that detects files named "METADATA". +114 */ +115 private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( +116 "EGG-INFO"); +117 +118 /** +119 * Filter that detects files named "METADATA". +120 */ +121 private static final NameFileFilter METADATA_FILTER = new NameFileFilter( +122 METADATA); +123 +124 /** +125 * Filter that detects files named "PKG-INFO". +126 */ +127 private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter( +128 PKG_INFO); +129 +130 /** +131 * The file filter used to determine which files this analyzer supports. +132 */ +133 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters( +134 METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build(); +135 +136 /** +137 * Returns the FileFilter +138 * +139 * @return the FileFilter +140 */ +141 @Override +142 protected FileFilter getFileFilter() { +143 return FILTER; +144 } +145 +146 /** +147 * Returns the name of the analyzer. +148 * +149 * @return the name of the analyzer. +150 */ +151 @Override +152 public String getName() { +153 return ANALYZER_NAME; +154 } +155 +156 /** +157 * Returns the phase that the analyzer is intended to run in. +158 * +159 * @return the phase that the analyzer is intended to run in. +160 */ +161 @Override +162 public AnalysisPhase getAnalysisPhase() { +163 return ANALYSIS_PHASE; +164 } +165 +166 /** +167 * Returns the key used in the properties file to reference the analyzer's enabled property. +168 * +169 * @return the analyzer's enabled property setting key +170 */ +171 @Override +172 protected String getAnalyzerEnabledSettingKey() { +173 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; +174 } +175 +176 @Override +177 protected void analyzeFileType(Dependency dependency, Engine engine) +178 throws AnalysisException { +179 final File actualFile = dependency.getActualFile(); +180 if (WHL_FILTER.accept(actualFile)) { +181 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, +182 METADATA_FILTER); +183 } else if (EGG_OR_ZIP.accept(actualFile)) { +184 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, +185 PKG_INFO_FILTER); +186 } else { +187 final String name = actualFile.getName(); +188 final boolean metadata = METADATA.equals(name); +189 if (metadata || PKG_INFO.equals(name)) { +190 final File parent = actualFile.getParentFile(); +191 final String parentName = parent.getName(); +192 dependency.setDisplayFileName(parentName + "/" + name); +193 if (parent.isDirectory() +194 && (metadata && parentName.endsWith(".dist-info") +195 || parentName.endsWith(".egg-info") || "EGG-INFO" +196 .equals(parentName))) { +197 collectWheelMetadata(dependency, actualFile); +198 } +199 } +200 } +201 } +202 +203 /** +204 * Collects the meta data from an archive. +205 * +206 * @param dependency the archive being scanned +207 * @param folderFilter the filter to apply to the folder +208 * @param metadataFilter the filter to apply to the meta data +209 * @throws AnalysisException thrown when there is a problem analyzing the dependency +210 */ +211 private void collectMetadataFromArchiveFormat(Dependency dependency, +212 FilenameFilter folderFilter, FilenameFilter metadataFilter) +213 throws AnalysisException { +214 final File temp = getNextTempDirectory(); +215 LOGGER.debug("{} exists? {}", temp, temp.exists()); +216 try { +217 ExtractionUtil.extractFilesUsingFilter( +218 new File(dependency.getActualFilePath()), temp, +219 metadataFilter); +220 } catch (ExtractionException ex) { +221 throw new AnalysisException(ex); +222 } +223 +224 collectWheelMetadata( +225 dependency, +226 getMatchingFile(getMatchingFile(temp, folderFilter), +227 metadataFilter)); +228 } +229 +230 /** +231 * Makes sure a usable temporary directory is available. +232 * +233 * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created +234 */ +235 @Override +236 protected void initializeFileTypeAnalyzer() throws Exception { +237 final File baseDir = Settings.getTempDirectory(); +238 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +239 if (!tempFileLocation.delete()) { +240 final String msg = String.format( +241 "Unable to delete temporary file '%s'.", +242 tempFileLocation.getAbsolutePath()); +243 throw new AnalysisException(msg); +244 } +245 if (!tempFileLocation.mkdirs()) { +246 final String msg = String.format( +247 "Unable to create directory '%s'.", +248 tempFileLocation.getAbsolutePath()); +249 throw new AnalysisException(msg); +250 } +251 } +252 +253 /** +254 * Deletes any files extracted from the Wheel during analysis. +255 */ +256 @Override +257 public void close() { +258 if (tempFileLocation != null && tempFileLocation.exists()) { +259 LOGGER.debug("Attempting to delete temporary files"); +260 final boolean success = FileUtils.delete(tempFileLocation); +261 if (!success) { +262 LOGGER.warn( +263 "Failed to delete some temporary files, see the log for more details"); +264 } +265 } +266 } +267 +268 /** +269 * Gathers evidence from the METADATA file. +270 * +271 * @param dependency the dependency being analyzed +272 * @param file a reference to the manifest/properties file +273 */ +274 private static void collectWheelMetadata(Dependency dependency, File file) { +275 final InternetHeaders headers = getManifestProperties(file); +276 addPropertyToEvidence(headers, dependency.getVersionEvidence(), +277 "Version", Confidence.HIGHEST); +278 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", +279 Confidence.HIGHEST); +280 final String url = headers.getHeader("Home-page", null); +281 final EvidenceCollection vendorEvidence = dependency +282 .getVendorEvidence(); +283 if (StringUtils.isNotBlank(url)) { +284 if (UrlStringUtils.isUrl(url)) { +285 vendorEvidence.addEvidence(METADATA, "vendor", url, +286 Confidence.MEDIUM); +287 } +288 } +289 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); +290 final String summary = headers.getHeader("Summary", null); +291 if (StringUtils.isNotBlank(summary)) { +292 JarAnalyzer +293 .addDescription(dependency, summary, METADATA, "summary"); +294 } +295 } +296 +297 /** +298 * Adds a value to the evidence collection. +299 * +300 * @param headers the properties collection +301 * @param evidence the evidence collection to add the value +302 * @param property the property name +303 * @param confidence the confidence of the evidence +304 */ +305 private static void addPropertyToEvidence(InternetHeaders headers, +306 EvidenceCollection evidence, String property, Confidence confidence) { +307 final String value = headers.getHeader(property, null); +308 LOGGER.debug("Property: {}, Value: {}", property, value); +309 if (StringUtils.isNotBlank(value)) { +310 evidence.addEvidence(METADATA, property, value, confidence); +311 } +312 } +313 +314 /** +315 * Returns a list of files that match the given filter, this does not recursively scan the directory. +316 * +317 * @param folder the folder to filter +318 * @param filter the filter to apply to the files in the directory +319 * @return the list of Files in the directory that match the provided filter +320 */ +321 private static File getMatchingFile(File folder, FilenameFilter filter) { +322 File result = null; +323 final File[] matches = folder.listFiles(filter); +324 if (null != matches && 1 == matches.length) { +325 result = matches[0]; +326 } +327 return result; +328 } +329 +330 /** +331 * Reads the manifest entries from the provided file. +332 * +333 * @param manifest the manifest +334 * @return the manifest entries +335 */ +336 private static InternetHeaders getManifestProperties(File manifest) { +337 final InternetHeaders result = new InternetHeaders(); +338 if (null == manifest) { +339 LOGGER.debug("Manifest file not found."); +340 } else { +341 try { +342 result.load(new AutoCloseInputStream(new BufferedInputStream( +343 new FileInputStream(manifest)))); +344 } catch (MessagingException e) { +345 LOGGER.warn(e.getMessage(), e); +346 } catch (FileNotFoundException e) { +347 LOGGER.warn(e.getMessage(), e); +348 } +349 } +350 return result; +351 } +352 +353 /** +354 * Retrieves the next temporary destination directory for extracting an archive. +355 * +356 * @return a directory +357 * @throws AnalysisException thrown if unable to create temporary directory +358 */ +359 private File getNextTempDirectory() throws AnalysisException { +360 File directory; +361 +362 // getting an exception for some directories not being able to be +363 // created; might be because the directory already exists? +364 do { +365 dirCount += 1; +366 directory = new File(tempFileLocation, String.valueOf(dirCount)); +367 } while (directory.exists()); +368 if (!directory.mkdirs()) { +369 throw new AnalysisException(String.format( +370 "Unable to create temp directory '%s'.", +371 directory.getAbsolutePath())); +372 } +373 return directory; +374 } +375 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html index 8bae17722..e87b494a2 100644 --- a/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html @@ -40,288 +40,295 @@ 32 import java.io.File; 33 import java.io.FileFilter; 34 import java.io.IOException; -35 import java.util.ArrayList; -36 import java.util.List; -37 import java.util.regex.Matcher; -38 import java.util.regex.Pattern; -39 -40 /** -41 * Used to analyze a Python package, and collect information that can be used to determine the associated CPE. -42 * -43 * @author Dale Visser -44 */ -45 public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { -46 -47 /** -48 * Used when compiling file scanning regex patterns. -49 */ -50 private static final int REGEX_OPTIONS = Pattern.DOTALL -51 | Pattern.CASE_INSENSITIVE; -52 -53 /** -54 * Filename extensions for files to be analyzed. -55 */ -56 private static final String EXTENSIONS = "py"; -57 -58 /** -59 * Pattern for matching the module docstring in a source file. -60 */ -61 private static final Pattern MODULE_DOCSTRING = Pattern.compile( -62 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); -63 -64 /** -65 * Matches assignments to version variables in Python source code. -66 */ -67 private static final Pattern VERSION_PATTERN = Pattern.compile( -68 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", -69 REGEX_OPTIONS); -70 -71 /** -72 * Matches assignments to title variables in Python source code. -73 */ -74 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); -75 -76 /** -77 * Matches assignments to summary variables in Python source code. -78 */ -79 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); -80 -81 /** -82 * Matches assignments to URL/URL variables in Python source code. -83 */ -84 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); -85 -86 /** -87 * Matches assignments to home page variables in Python source code. -88 */ -89 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); -90 -91 /** -92 * Matches assignments to author variables in Python source code. -93 */ -94 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); -95 -96 /** -97 * Filter that detects files named "__init__.py". -98 */ -99 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); -100 -101 /** -102 * The file filter for python files. -103 */ -104 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); -105 -106 /** -107 * Returns the name of the Python Package Analyzer. -108 * -109 * @return the name of the analyzer -110 */ -111 @Override -112 public String getName() { -113 return "Python Package Analyzer"; -114 } -115 -116 /** -117 * Tell that we are used for information collection. -118 * -119 * @return INFORMATION_COLLECTION -120 */ -121 @Override -122 public AnalysisPhase getAnalysisPhase() { -123 return AnalysisPhase.INFORMATION_COLLECTION; -124 } -125 -126 /** -127 * The file filter used to determine which files this analyzer supports. -128 */ -129 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); -130 -131 /** -132 * Returns the FileFilter -133 * -134 * @return the FileFilter -135 */ -136 @Override -137 protected FileFilter getFileFilter() { -138 return FILTER; -139 } -140 -141 /** -142 * No-op initializer implementation. -143 * -144 * @throws Exception never thrown -145 */ -146 @Override -147 protected void initializeFileTypeAnalyzer() throws Exception { -148 // Nothing to do here. -149 } -150 -151 /** -152 * Utility function to create a regex pattern matcher. -153 * -154 * @param name the value to use when constructing the assignment pattern -155 * @return the compiled Pattern -156 */ -157 private static Pattern compileAssignPattern(String name) { -158 return Pattern.compile( -159 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), -160 REGEX_OPTIONS); -161 } -162 -163 /** -164 * Analyzes python packages and adds evidence to the dependency. -165 * -166 * @param dependency the dependency being analyzed -167 * @param engine the engine being used to perform the scan -168 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency -169 */ -170 @Override -171 protected void analyzeFileType(Dependency dependency, Engine engine) -172 throws AnalysisException { -173 final File file = dependency.getActualFile(); -174 final File parent = file.getParentFile(); -175 final String parentName = parent.getName(); -176 boolean found = false; -177 if (INIT_PY_FILTER.accept(file)) { -178 final File[] fileList = parent.listFiles(PY_FILTER); -179 if (fileList != null) { -180 for (final File sourceFile : fileList) { -181 found |= analyzeFileContents(dependency, sourceFile); -182 } -183 } -184 } -185 if (found) { -186 dependency.setDisplayFileName(parentName + "/__init__.py"); -187 dependency.getProductEvidence().addEvidence(file.getName(), -188 "PackageName", parentName, Confidence.HIGH); -189 } else { -190 // copy, alter and set in case some other thread is iterating over -191 final List<Dependency> dependencies = new ArrayList<Dependency>( -192 engine.getDependencies()); -193 dependencies.remove(dependency); -194 engine.setDependencies(dependencies); -195 } -196 } -197 -198 /** -199 * This should gather information from leading docstrings, file comments, and assignments to __version__, __title__, -200 * __summary__, __uri__, __url__, __home*page__, __author__, and their all caps equivalents. -201 * -202 * @param dependency the dependency being analyzed -203 * @param file the file name to analyze -204 * @return whether evidence was found -205 * @throws AnalysisException thrown if there is an unrecoverable error -206 */ -207 private boolean analyzeFileContents(Dependency dependency, File file) -208 throws AnalysisException { -209 String contents; -210 try { -211 contents = FileUtils.readFileToString(file).trim(); -212 } catch (IOException e) { -213 throw new AnalysisException( -214 "Problem occurred while reading dependency file.", e); -215 } -216 boolean found = false; -217 if (!contents.isEmpty()) { -218 final String source = file.getName(); -219 found = gatherEvidence(VERSION_PATTERN, contents, source, -220 dependency.getVersionEvidence(), "SourceVersion", -221 Confidence.MEDIUM); -222 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents, -223 source, "summary"); -224 if (INIT_PY_FILTER.accept(file)) { -225 found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2, -226 contents, source, "docstring"); -227 } -228 found |= gatherEvidence(TITLE_PATTERN, contents, source, -229 dependency.getProductEvidence(), "SourceTitle", -230 Confidence.LOW); -231 final EvidenceCollection vendorEvidence = dependency -232 .getVendorEvidence(); -233 found |= gatherEvidence(AUTHOR_PATTERN, contents, source, -234 vendorEvidence, "SourceAuthor", Confidence.MEDIUM); -235 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, -236 source, "URL", contents); -237 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, -238 vendorEvidence, source, "HomePage", contents); -239 } -240 return found; -241 } -242 -243 /** -244 * Adds summary information to the dependency -245 * -246 * @param dependency the dependency being analyzed -247 * @param pattern the pattern used to perform analysis -248 * @param group the group from the pattern that indicates the data to use -249 * @param contents the data being analyzed -250 * @param source the source name to use when recording the evidence -251 * @param key the key name to use when recording the evidence -252 * @return true if evidence was collected; otherwise false -253 */ -254 private boolean addSummaryInfo(Dependency dependency, Pattern pattern, -255 int group, String contents, String source, String key) { -256 final Matcher matcher = pattern.matcher(contents); -257 final boolean found = matcher.find(); -258 if (found) { -259 JarAnalyzer.addDescription(dependency, matcher.group(group), -260 source, key); -261 } -262 return found; -263 } -264 -265 /** -266 * Collects evidence from the home page URL. -267 * -268 * @param pattern the pattern to match -269 * @param evidence the evidence collection to add the evidence to -270 * @param source the source of the evidence -271 * @param name the name of the evidence -272 * @param contents the home page URL -273 * @return true if evidence was collected; otherwise false -274 */ -275 private boolean gatherHomePageEvidence(Pattern pattern, -276 EvidenceCollection evidence, String source, String name, -277 String contents) { -278 final Matcher matcher = pattern.matcher(contents); -279 boolean found = false; -280 if (matcher.find()) { -281 final String url = matcher.group(4); -282 if (UrlStringUtils.isUrl(url)) { -283 found = true; -284 evidence.addEvidence(source, name, url, Confidence.MEDIUM); -285 } -286 } -287 return found; -288 } -289 -290 /** -291 * Gather evidence from a Python source file using the given string assignment regex pattern. -292 * -293 * @param pattern to scan contents with -294 * @param contents of Python source file -295 * @param source for storing evidence -296 * @param evidence to store evidence in -297 * @param name of evidence -298 * @param confidence in evidence -299 * @return whether evidence was found -300 */ -301 private boolean gatherEvidence(Pattern pattern, String contents, -302 String source, EvidenceCollection evidence, String name, -303 Confidence confidence) { -304 final Matcher matcher = pattern.matcher(contents); -305 final boolean found = matcher.find(); -306 if (found) { -307 evidence.addEvidence(source, name, matcher.group(4), confidence); -308 } -309 return found; -310 } -311 -312 @Override -313 protected String getAnalyzerEnabledSettingKey() { -314 return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED; -315 } -316 } +35 import java.nio.charset.Charset; +36 import java.util.ArrayList; +37 import java.util.List; +38 import java.util.regex.Matcher; +39 import java.util.regex.Pattern; +40 +41 /** +42 * Used to analyze a Python package, and collect information that can be used to +43 * determine the associated CPE. +44 * +45 * @author Dale Visser +46 */ +47 @Experimental +48 public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { +49 +50 /** +51 * Used when compiling file scanning regex patterns. +52 */ +53 private static final int REGEX_OPTIONS = Pattern.DOTALL +54 | Pattern.CASE_INSENSITIVE; +55 +56 /** +57 * Filename extensions for files to be analyzed. +58 */ +59 private static final String EXTENSIONS = "py"; +60 +61 /** +62 * Pattern for matching the module docstring in a source file. +63 */ +64 private static final Pattern MODULE_DOCSTRING = Pattern.compile( +65 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); +66 +67 /** +68 * Matches assignments to version variables in Python source code. +69 */ +70 private static final Pattern VERSION_PATTERN = Pattern.compile( +71 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", +72 REGEX_OPTIONS); +73 +74 /** +75 * Matches assignments to title variables in Python source code. +76 */ +77 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); +78 +79 /** +80 * Matches assignments to summary variables in Python source code. +81 */ +82 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); +83 +84 /** +85 * Matches assignments to URL/URL variables in Python source code. +86 */ +87 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); +88 +89 /** +90 * Matches assignments to home page variables in Python source code. +91 */ +92 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); +93 +94 /** +95 * Matches assignments to author variables in Python source code. +96 */ +97 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); +98 +99 /** +100 * Filter that detects files named "__init__.py". +101 */ +102 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); +103 +104 /** +105 * The file filter for python files. +106 */ +107 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); +108 +109 /** +110 * Returns the name of the Python Package Analyzer. +111 * +112 * @return the name of the analyzer +113 */ +114 @Override +115 public String getName() { +116 return "Python Package Analyzer"; +117 } +118 +119 /** +120 * Tell that we are used for information collection. +121 * +122 * @return INFORMATION_COLLECTION +123 */ +124 @Override +125 public AnalysisPhase getAnalysisPhase() { +126 return AnalysisPhase.INFORMATION_COLLECTION; +127 } +128 +129 /** +130 * The file filter used to determine which files this analyzer supports. +131 */ +132 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +133 +134 /** +135 * Returns the FileFilter +136 * +137 * @return the FileFilter +138 */ +139 @Override +140 protected FileFilter getFileFilter() { +141 return FILTER; +142 } +143 +144 /** +145 * No-op initializer implementation. +146 * +147 * @throws Exception never thrown +148 */ +149 @Override +150 protected void initializeFileTypeAnalyzer() throws Exception { +151 // Nothing to do here. +152 } +153 +154 /** +155 * Utility function to create a regex pattern matcher. +156 * +157 * @param name the value to use when constructing the assignment pattern +158 * @return the compiled Pattern +159 */ +160 private static Pattern compileAssignPattern(String name) { +161 return Pattern.compile( +162 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), +163 REGEX_OPTIONS); +164 } +165 +166 /** +167 * Analyzes python packages and adds evidence to the dependency. +168 * +169 * @param dependency the dependency being analyzed +170 * @param engine the engine being used to perform the scan +171 * @throws AnalysisException thrown if there is an unrecoverable error +172 * analyzing the dependency +173 */ +174 @Override +175 protected void analyzeFileType(Dependency dependency, Engine engine) +176 throws AnalysisException { +177 final File file = dependency.getActualFile(); +178 final File parent = file.getParentFile(); +179 final String parentName = parent.getName(); +180 if (INIT_PY_FILTER.accept(file)) { +181 //by definition, the containing folder of __init__.py is considered the package, even the file is empty: +182 //"The __init__.py files are required to make Python treat the directories as containing packages" +183 //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html; +184 dependency.setDisplayFileName(parentName + "/__init__.py"); +185 dependency.getProductEvidence().addEvidence(file.getName(), +186 "PackageName", parentName, Confidence.HIGHEST); +187 +188 final File[] fileList = parent.listFiles(PY_FILTER); +189 if (fileList != null) { +190 for (final File sourceFile : fileList) { +191 analyzeFileContents(dependency, sourceFile); +192 } +193 } +194 } else { +195 // copy, alter and set in case some other thread is iterating over +196 final List<Dependency> dependencies = new ArrayList<Dependency>( +197 engine.getDependencies()); +198 dependencies.remove(dependency); +199 engine.setDependencies(dependencies); +200 } +201 } +202 +203 /** +204 * This should gather information from leading docstrings, file comments, +205 * and assignments to __version__, __title__, __summary__, __uri__, __url__, +206 * __home*page__, __author__, and their all caps equivalents. +207 * +208 * @param dependency the dependency being analyzed +209 * @param file the file name to analyze +210 * @return whether evidence was found +211 * @throws AnalysisException thrown if there is an unrecoverable error +212 */ +213 private boolean analyzeFileContents(Dependency dependency, File file) +214 throws AnalysisException { +215 String contents; +216 try { +217 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); +218 } catch (IOException e) { +219 throw new AnalysisException( +220 "Problem occurred while reading dependency file.", e); +221 } +222 boolean found = false; +223 if (!contents.isEmpty()) { +224 final String source = file.getName(); +225 found = gatherEvidence(VERSION_PATTERN, contents, source, +226 dependency.getVersionEvidence(), "SourceVersion", +227 Confidence.MEDIUM); +228 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents, +229 source, "summary"); +230 if (INIT_PY_FILTER.accept(file)) { +231 found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2, +232 contents, source, "docstring"); +233 } +234 found |= gatherEvidence(TITLE_PATTERN, contents, source, +235 dependency.getProductEvidence(), "SourceTitle", +236 Confidence.LOW); +237 final EvidenceCollection vendorEvidence = dependency +238 .getVendorEvidence(); +239 found |= gatherEvidence(AUTHOR_PATTERN, contents, source, +240 vendorEvidence, "SourceAuthor", Confidence.MEDIUM); +241 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, +242 source, "URL", contents); +243 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, +244 vendorEvidence, source, "HomePage", contents); +245 } +246 return found; +247 } +248 +249 /** +250 * Adds summary information to the dependency +251 * +252 * @param dependency the dependency being analyzed +253 * @param pattern the pattern used to perform analysis +254 * @param group the group from the pattern that indicates the data to use +255 * @param contents the data being analyzed +256 * @param source the source name to use when recording the evidence +257 * @param key the key name to use when recording the evidence +258 * @return true if evidence was collected; otherwise false +259 */ +260 private boolean addSummaryInfo(Dependency dependency, Pattern pattern, +261 int group, String contents, String source, String key) { +262 final Matcher matcher = pattern.matcher(contents); +263 final boolean found = matcher.find(); +264 if (found) { +265 JarAnalyzer.addDescription(dependency, matcher.group(group), +266 source, key); +267 } +268 return found; +269 } +270 +271 /** +272 * Collects evidence from the home page URL. +273 * +274 * @param pattern the pattern to match +275 * @param evidence the evidence collection to add the evidence to +276 * @param source the source of the evidence +277 * @param name the name of the evidence +278 * @param contents the home page URL +279 * @return true if evidence was collected; otherwise false +280 */ +281 private boolean gatherHomePageEvidence(Pattern pattern, +282 EvidenceCollection evidence, String source, String name, +283 String contents) { +284 final Matcher matcher = pattern.matcher(contents); +285 boolean found = false; +286 if (matcher.find()) { +287 final String url = matcher.group(4); +288 if (UrlStringUtils.isUrl(url)) { +289 found = true; +290 evidence.addEvidence(source, name, url, Confidence.MEDIUM); +291 } +292 } +293 return found; +294 } +295 +296 /** +297 * Gather evidence from a Python source file using the given string +298 * assignment regex pattern. +299 * +300 * @param pattern to scan contents with +301 * @param contents of Python source file +302 * @param source for storing evidence +303 * @param evidence to store evidence in +304 * @param name of evidence +305 * @param confidence in evidence +306 * @return whether evidence was found +307 */ +308 private boolean gatherEvidence(Pattern pattern, String contents, +309 String source, EvidenceCollection evidence, String name, +310 Confidence confidence) { +311 final Matcher matcher = pattern.matcher(contents); +312 final boolean found = matcher.find(); +313 if (found) { +314 evidence.addEvidence(source, name, matcher.group(4), confidence); +315 } +316 return found; +317 } +318 +319 @Override +320 protected String getAnalyzerEnabledSettingKey() { +321 return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED; +322 } +323 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html index 93be2b0d4..d14417ea9 100644 --- a/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html @@ -25,329 +25,458 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import org.apache.commons.io.FileUtils; -21 import org.owasp.dependencycheck.Engine; -22 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -23 import org.owasp.dependencycheck.dependency.Confidence; -24 import org.owasp.dependencycheck.dependency.Dependency; -25 import org.owasp.dependencycheck.dependency.Reference; -26 import org.owasp.dependencycheck.dependency.Vulnerability; -27 import org.owasp.dependencycheck.utils.FileFilterBuilder; -28 import org.owasp.dependencycheck.utils.Settings; -29 import org.slf4j.Logger; -30 import org.slf4j.LoggerFactory; -31 -32 import java.io.*; -33 import java.util.*; -34 -35 /** -36 * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party bundle-audit tool. -37 * -38 * @author Dale Visser -39 */ -40 public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { -41 -42 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class); +20 import java.io.BufferedReader; +21 import java.io.File; +22 import java.io.FileFilter; +23 import java.io.IOException; +24 import java.io.InputStreamReader; +25 import java.util.ArrayList; +26 import java.util.HashMap; +27 import java.util.List; +28 import java.util.Map; +29 import java.nio.charset.Charset; +30 import org.apache.commons.io.FileUtils; +31 import org.owasp.dependencycheck.Engine; +32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +33 import org.owasp.dependencycheck.data.nvdcve.CveDB; +34 import org.owasp.dependencycheck.dependency.Confidence; +35 import org.owasp.dependencycheck.dependency.Dependency; +36 import org.owasp.dependencycheck.dependency.Reference; +37 import org.owasp.dependencycheck.dependency.Vulnerability; +38 import org.owasp.dependencycheck.utils.FileFilterBuilder; +39 import org.owasp.dependencycheck.utils.Settings; +40 import org.slf4j.Logger; +41 import org.slf4j.LoggerFactory; +42 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; 43 -44 /** -45 * The name of the analyzer. -46 */ -47 private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer"; -48 -49 /** -50 * The phase that this analyzer is intended to run in. -51 */ -52 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; -53 -54 private static final FileFilter FILTER -55 = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); -56 public static final String NAME = "Name: "; -57 public static final String VERSION = "Version: "; -58 public static final String ADVISORY = "Advisory: "; -59 public static final String CRITICALITY = "Criticality: "; -60 -61 /** -62 * @return a filter that accepts files named Gemfile.lock -63 */ -64 @Override -65 protected FileFilter getFileFilter() { -66 return FILTER; -67 } -68 -69 /** -70 * Launch bundle-audit. -71 * -72 * @return a handle to the process -73 */ -74 private Process launchBundleAudit(File folder) throws AnalysisException { -75 if (!folder.isDirectory()) { -76 throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath())); -77 } -78 final List<String> args = new ArrayList<String>(); -79 final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH); -80 args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath); -81 args.add("check"); -82 args.add("--verbose"); -83 final ProcessBuilder builder = new ProcessBuilder(args); -84 builder.directory(folder); -85 try { -86 LOGGER.info("Launching: " + args + " from " + folder); -87 return builder.start(); -88 } catch (IOException ioe) { -89 throw new AnalysisException("bundle-audit failure", ioe); -90 } -91 } -92 -93 /** -94 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location. -95 * -96 * @throws Exception if anything goes wrong -97 */ -98 @Override -99 public void initializeFileTypeAnalyzer() throws Exception { -100 // Now, need to see if bundle-audit actually runs from this location. -101 Process process = null; -102 try { -103 process = launchBundleAudit(Settings.getTempDirectory()); -104 } -105 catch(AnalysisException ae) { -106 LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME); -107 setEnabled(false); -108 throw ae; -109 } -110 -111 int exitValue = process.waitFor(); -112 if (0 == exitValue) { -113 LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue); -114 setEnabled(false); -115 throw new AnalysisException("Unexpected exit code from bundle-audit process."); -116 } else { -117 BufferedReader reader = null; -118 try { -119 reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); -120 if (!reader.ready()) { -121 LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME); -122 setEnabled(false); -123 throw new AnalysisException("Bundle-audit error stream unexpectedly not ready."); -124 } else { -125 final String line = reader.readLine(); -126 if (line == null || !line.contains("Errno::ENOENT")) { -127 LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line); -128 setEnabled(false); -129 throw new AnalysisException("Unexpected bundle-audit output."); -130 } -131 } -132 } finally { -133 if (null != reader) { -134 reader.close(); -135 } -136 } -137 } -138 -139 if (isEnabled()) { -140 LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " -141 + "occasionally to keep its database up to date."); -142 } -143 } -144 -145 /** -146 * Returns the name of the analyzer. -147 * -148 * @return the name of the analyzer. -149 */ -150 @Override -151 public String getName() { -152 return ANALYZER_NAME; -153 } -154 -155 /** -156 * Returns the phase that the analyzer is intended to run in. -157 * -158 * @return the phase that the analyzer is intended to run in. -159 */ -160 @Override -161 public AnalysisPhase getAnalysisPhase() { -162 return ANALYSIS_PHASE; -163 } -164 -165 /** -166 * Returns the key used in the properties file to reference the analyzer's enabled property. -167 * -168 * @return the analyzer's enabled property setting key -169 */ -170 @Override -171 protected String getAnalyzerEnabledSettingKey() { -172 return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED; -173 } -174 -175 /** -176 * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have successfully initialized, and it will be necessary -177 * to disable {@link RubyGemspecAnalyzer}. -178 */ -179 private boolean needToDisableGemspecAnalyzer = true; -180 -181 @Override -182 protected void analyzeFileType(Dependency dependency, Engine engine) -183 throws AnalysisException { -184 if (needToDisableGemspecAnalyzer) { -185 boolean failed = true; -186 final String className = RubyGemspecAnalyzer.class.getName(); -187 for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) { -188 if (analyzer instanceof RubyGemspecAnalyzer) { -189 ((RubyGemspecAnalyzer) analyzer).setEnabled(false); -190 LOGGER.info("Disabled " + className + " to avoid noisy duplicate results."); -191 failed = false; -192 } -193 } -194 if (failed) { -195 LOGGER.warn("Did not find" + className + '.'); -196 } -197 needToDisableGemspecAnalyzer = false; -198 } -199 final File parentFile = dependency.getActualFile().getParentFile(); -200 final Process process = launchBundleAudit(parentFile); -201 try { -202 process.waitFor(); -203 } catch (InterruptedException ie) { -204 throw new AnalysisException("bundle-audit process interrupted", ie); -205 } -206 BufferedReader rdr = null; -207 try { -208 BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); -209 while(errReader.ready()) { -210 String error = errReader.readLine(); -211 LOGGER.warn(error); -212 } -213 rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); -214 processBundlerAuditOutput(dependency, engine, rdr); -215 } catch (IOException ioe) { -216 LOGGER.warn("bundle-audit failure", ioe); -217 } finally { -218 if (null != rdr) { -219 try { -220 rdr.close(); -221 } catch (IOException ioe) { -222 LOGGER.warn("bundle-audit close failure", ioe); -223 } -224 } -225 } -226 -227 } -228 -229 private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException { -230 final String parentName = original.getActualFile().getParentFile().getName(); -231 final String fileName = original.getFileName(); -232 Dependency dependency = null; -233 Vulnerability vulnerability = null; -234 String gem = null; -235 final Map<String, Dependency> map = new HashMap<String, Dependency>(); -236 boolean appendToDescription = false; -237 while (rdr.ready()) { -238 final String nextLine = rdr.readLine(); -239 if (null == nextLine) { -240 break; -241 } else if (nextLine.startsWith(NAME)) { -242 appendToDescription = false; -243 gem = nextLine.substring(NAME.length()); -244 if (!map.containsKey(gem)) { -245 map.put(gem, createDependencyForGem(engine, parentName, fileName, gem)); -246 } -247 dependency = map.get(gem); -248 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -249 } else if (nextLine.startsWith(VERSION)) { -250 vulnerability = createVulnerability(parentName, dependency, vulnerability, gem, nextLine); -251 } else if (nextLine.startsWith(ADVISORY)) { -252 setVulnerabilityName(parentName, dependency, vulnerability, nextLine); -253 } else if (nextLine.startsWith(CRITICALITY)) { -254 addCriticalityToVulnerability(parentName, vulnerability, nextLine); -255 } else if (nextLine.startsWith("URL: ")) { -256 addReferenceToVulnerability(parentName, vulnerability, nextLine); -257 } else if (nextLine.startsWith("Description:")) { -258 appendToDescription = true; -259 if (null != vulnerability) { -260 vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 indicates unknown). See link below for full details. *** "); -261 } -262 } else if (appendToDescription) { -263 if (null != vulnerability) { -264 vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n"); -265 } -266 } -267 } -268 } -269 -270 private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) { -271 final String advisory = nextLine.substring((ADVISORY.length())); -272 if (null != vulnerability) { -273 vulnerability.setName(advisory); -274 } -275 if (null != dependency) { -276 dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE -277 } -278 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -279 } -280 -281 private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { -282 final String url = nextLine.substring(("URL: ").length()); -283 if (null != vulnerability) { -284 Reference ref = new Reference(); -285 ref.setName(vulnerability.getName()); -286 ref.setSource("bundle-audit"); -287 ref.setUrl(url); -288 vulnerability.getReferences().add(ref); -289 } -290 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -291 } -292 -293 private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { -294 if (null != vulnerability) { -295 final String criticality = nextLine.substring(CRITICALITY.length()).trim(); -296 if ("High".equals(criticality)) { -297 vulnerability.setCvssScore(8.5f); -298 } else if ("Medium".equals(criticality)) { -299 vulnerability.setCvssScore(5.5f); -300 } else if ("Low".equals(criticality)) { -301 vulnerability.setCvssScore(2.0f); -302 } else { -303 vulnerability.setCvssScore(-1.0f); -304 } -305 } -306 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -307 } -308 -309 private Vulnerability createVulnerability(String parentName, Dependency dependency, Vulnerability vulnerability, String gem, String nextLine) { -310 if (null != dependency) { -311 final String version = nextLine.substring(VERSION.length()); -312 dependency.getVersionEvidence().addEvidence( -313 "bundler-audit", -314 "Version", -315 version, -316 Confidence.HIGHEST); -317 vulnerability = new Vulnerability(); // don't add to dependency until we have name set later -318 vulnerability.setMatchedCPE( -319 String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version), -320 null); -321 vulnerability.setCvssAccessVector("-"); -322 vulnerability.setCvssAccessComplexity("-"); -323 vulnerability.setCvssAuthentication("-"); -324 vulnerability.setCvssAvailabilityImpact("-"); -325 vulnerability.setCvssConfidentialityImpact("-"); -326 vulnerability.setCvssIntegrityImpact("-"); -327 } -328 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -329 return vulnerability; -330 } -331 -332 private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String gem) throws IOException { -333 final File tempFile = File.createTempFile("Gemfile-" + gem, ".lock", Settings.getTempDirectory()); -334 final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem); -335 FileUtils.write(tempFile, displayFileName); // unique contents to avoid dependency bundling -336 final Dependency dependency = new Dependency(tempFile); -337 dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST); -338 dependency.setDisplayFileName(displayFileName); -339 engine.getDependencies().add(dependency); -340 return dependency; -341 } -342 } +44 /** +45 * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party +46 * bundle-audit tool. +47 * +48 * @author Dale Visser +49 */ +50 @Experimental +51 public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { +52 +53 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class); +54 +55 /** +56 * The name of the analyzer. +57 */ +58 private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer"; +59 +60 /** +61 * The phase that this analyzer is intended to run in. +62 */ +63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; +64 /** +65 * The filter defining which files will be analyzed. +66 */ +67 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); +68 /** +69 * Name. +70 */ +71 public static final String NAME = "Name: "; +72 /** +73 * Version. +74 */ +75 public static final String VERSION = "Version: "; +76 /** +77 * Advisory. +78 */ +79 public static final String ADVISORY = "Advisory: "; +80 /** +81 * Criticality. +82 */ +83 public static final String CRITICALITY = "Criticality: "; +84 +85 /** +86 * The DAL. +87 */ +88 private CveDB cvedb; +89 +90 /** +91 * @return a filter that accepts files named Gemfile.lock +92 */ +93 @Override +94 protected FileFilter getFileFilter() { +95 return FILTER; +96 } +97 +98 /** +99 * Launch bundle-audit. +100 * +101 * @param folder directory that contains bundle audit +102 * @return a handle to the process +103 * @throws AnalysisException thrown when there is an issue launching bundle +104 * audit +105 */ +106 private Process launchBundleAudit(File folder) throws AnalysisException { +107 if (!folder.isDirectory()) { +108 throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath())); +109 } +110 final List<String> args = new ArrayList<String>(); +111 final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH); +112 args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath); +113 args.add("check"); +114 args.add("--verbose"); +115 final ProcessBuilder builder = new ProcessBuilder(args); +116 builder.directory(folder); +117 try { +118 LOGGER.info("Launching: " + args + " from " + folder); +119 return builder.start(); +120 } catch (IOException ioe) { +121 throw new AnalysisException("bundle-audit failure", ioe); +122 } +123 } +124 +125 /** +126 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a +127 * temporary location. +128 * +129 * @throws Exception if anything goes wrong +130 */ +131 @Override +132 public void initializeFileTypeAnalyzer() throws Exception { +133 try { +134 cvedb = new CveDB(); +135 cvedb.open(); +136 } catch (DatabaseException ex) { +137 LOGGER.warn("Exception opening the database"); +138 LOGGER.debug("error", ex); +139 setEnabled(false); +140 throw ex; +141 } +142 // Now, need to see if bundle-audit actually runs from this location. +143 Process process = null; +144 try { +145 process = launchBundleAudit(Settings.getTempDirectory()); +146 } catch (AnalysisException ae) { +147 LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME); +148 setEnabled(false); +149 cvedb.close(); +150 cvedb = null; +151 throw ae; +152 } +153 +154 final int exitValue = process.waitFor(); +155 if (0 == exitValue) { +156 LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue); +157 setEnabled(false); +158 throw new AnalysisException("Unexpected exit code from bundle-audit process."); +159 } else { +160 BufferedReader reader = null; +161 try { +162 reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); +163 if (!reader.ready()) { +164 LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME); +165 setEnabled(false); +166 throw new AnalysisException("Bundle-audit error stream unexpectedly not ready."); +167 } else { +168 final String line = reader.readLine(); +169 if (line == null || !line.contains("Errno::ENOENT")) { +170 LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line); +171 setEnabled(false); +172 throw new AnalysisException("Unexpected bundle-audit output."); +173 } +174 } +175 } finally { +176 if (null != reader) { +177 reader.close(); +178 } +179 } +180 } +181 +182 if (isEnabled()) { +183 LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " +184 + "occasionally to keep its database up to date."); +185 } +186 } +187 +188 /** +189 * Returns the name of the analyzer. +190 * +191 * @return the name of the analyzer. +192 */ +193 @Override +194 public String getName() { +195 return ANALYZER_NAME; +196 } +197 +198 /** +199 * Returns the phase that the analyzer is intended to run in. +200 * +201 * @return the phase that the analyzer is intended to run in. +202 */ +203 @Override +204 public AnalysisPhase getAnalysisPhase() { +205 return ANALYSIS_PHASE; +206 } +207 +208 /** +209 * Returns the key used in the properties file to reference the analyzer's +210 * enabled property. +211 * +212 * @return the analyzer's enabled property setting key +213 */ +214 @Override +215 protected String getAnalyzerEnabledSettingKey() { +216 return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED; +217 } +218 +219 /** +220 * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have +221 * successfully initialized, and it will be necessary to disable +222 * {@link RubyGemspecAnalyzer}. +223 */ +224 private boolean needToDisableGemspecAnalyzer = true; +225 +226 /** +227 * Determines if the analyzer can analyze the given file type. +228 * +229 * @param dependency the dependency to determine if it can analyze +230 * @param engine the dependency-check engine +231 * @throws AnalysisException thrown if there is an analysis exception. +232 */ +233 @Override +234 protected void analyzeFileType(Dependency dependency, Engine engine) +235 throws AnalysisException { +236 if (needToDisableGemspecAnalyzer) { +237 boolean failed = true; +238 final String className = RubyGemspecAnalyzer.class.getName(); +239 for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) { +240 if (analyzer instanceof RubyBundlerAnalyzer) { +241 ((RubyBundlerAnalyzer) analyzer).setEnabled(false); +242 LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results."); +243 } else if (analyzer instanceof RubyGemspecAnalyzer) { +244 ((RubyGemspecAnalyzer) analyzer).setEnabled(false); +245 LOGGER.info("Disabled " + className + " to avoid noisy duplicate results."); +246 failed = false; +247 } +248 } +249 if (failed) { +250 LOGGER.warn("Did not find " + className + '.'); +251 } +252 needToDisableGemspecAnalyzer = false; +253 } +254 final File parentFile = dependency.getActualFile().getParentFile(); +255 final Process process = launchBundleAudit(parentFile); +256 try { +257 process.waitFor(); +258 } catch (InterruptedException ie) { +259 throw new AnalysisException("bundle-audit process interrupted", ie); +260 } +261 BufferedReader rdr = null; +262 BufferedReader errReader = null; +263 try { +264 errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); +265 while (errReader.ready()) { +266 final String error = errReader.readLine(); +267 LOGGER.warn(error); +268 } +269 rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); +270 processBundlerAuditOutput(dependency, engine, rdr); +271 } catch (IOException ioe) { +272 LOGGER.warn("bundle-audit failure", ioe); +273 } finally { +274 if (errReader != null) { +275 try { +276 errReader.close(); +277 } catch (IOException ioe) { +278 LOGGER.warn("bundle-audit close failure", ioe); +279 } +280 } +281 if (null != rdr) { +282 try { +283 rdr.close(); +284 } catch (IOException ioe) { +285 LOGGER.warn("bundle-audit close failure", ioe); +286 } +287 } +288 } +289 +290 } +291 +292 /** +293 * Processes the bundler audit output. +294 * +295 * @param original the dependency +296 * @param engine the dependency-check engine +297 * @param rdr the reader of the report +298 * @throws IOException thrown if the report cannot be read. +299 */ +300 private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException { +301 final String parentName = original.getActualFile().getParentFile().getName(); +302 final String fileName = original.getFileName(); +303 final String filePath = original.getFilePath(); +304 Dependency dependency = null; +305 Vulnerability vulnerability = null; +306 String gem = null; +307 final Map<String, Dependency> map = new HashMap<String, Dependency>(); +308 boolean appendToDescription = false; +309 while (rdr.ready()) { +310 final String nextLine = rdr.readLine(); +311 if (null == nextLine) { +312 break; +313 } else if (nextLine.startsWith(NAME)) { +314 appendToDescription = false; +315 gem = nextLine.substring(NAME.length()); +316 if (!map.containsKey(gem)) { +317 map.put(gem, createDependencyForGem(engine, parentName, fileName, filePath, gem)); +318 } +319 dependency = map.get(gem); +320 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +321 } else if (nextLine.startsWith(VERSION)) { +322 vulnerability = createVulnerability(parentName, dependency, gem, nextLine); +323 } else if (nextLine.startsWith(ADVISORY)) { +324 setVulnerabilityName(parentName, dependency, vulnerability, nextLine); +325 } else if (nextLine.startsWith(CRITICALITY)) { +326 addCriticalityToVulnerability(parentName, vulnerability, nextLine); +327 } else if (nextLine.startsWith("URL: ")) { +328 addReferenceToVulnerability(parentName, vulnerability, nextLine); +329 } else if (nextLine.startsWith("Description:")) { +330 appendToDescription = true; +331 if (null != vulnerability) { +332 vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. " +333 + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 " +334 + " indicates unknown). See link below for full details. *** "); +335 } +336 } else if (appendToDescription) { +337 if (null != vulnerability) { +338 vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n"); +339 } +340 } +341 } +342 } +343 +344 /** +345 * Sets the vulnerability name. +346 * +347 * @param parentName the parent name +348 * @param dependency the dependency +349 * @param vulnerability the vulnerability +350 * @param nextLine the line to parse +351 */ +352 private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) { +353 final String advisory = nextLine.substring((ADVISORY.length())); +354 if (null != vulnerability) { +355 vulnerability.setName(advisory); +356 } +357 if (null != dependency) { +358 dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE +359 } +360 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +361 } +362 +363 /** +364 * Adds a reference to the vulnerability. +365 * +366 * @param parentName the parent name +367 * @param vulnerability the vulnerability +368 * @param nextLine the line to parse +369 */ +370 private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { +371 final String url = nextLine.substring(("URL: ").length()); +372 if (null != vulnerability) { +373 final Reference ref = new Reference(); +374 ref.setName(vulnerability.getName()); +375 ref.setSource("bundle-audit"); +376 ref.setUrl(url); +377 vulnerability.getReferences().add(ref); +378 } +379 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +380 } +381 +382 /** +383 * Adds the criticality to the vulnerability +384 * +385 * @param parentName the parent name +386 * @param vulnerability the vulnerability +387 * @param nextLine the line to parse +388 */ +389 private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { +390 if (null != vulnerability) { +391 final String criticality = nextLine.substring(CRITICALITY.length()).trim(); +392 float score = -1.0f; +393 Vulnerability v = null; +394 try { +395 v = cvedb.getVulnerability(vulnerability.getName()); +396 } catch (DatabaseException ex) { +397 LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName()); +398 } +399 if (v != null) { +400 score = v.getCvssScore(); +401 } else if ("High".equalsIgnoreCase(criticality)) { +402 score = 8.5f; +403 } else if ("Medium".equalsIgnoreCase(criticality)) { +404 score = 5.5f; +405 } else if ("Low".equalsIgnoreCase(criticality)) { +406 score = 2.0f; +407 } +408 vulnerability.setCvssScore(score); +409 } +410 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +411 } +412 +413 /** +414 * Creates a vulnerability. +415 * +416 * @param parentName the parent name +417 * @param dependency the dependency +418 * @param gem the gem name +419 * @param nextLine the line to parse +420 * @return the vulnerability +421 */ +422 private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) { +423 Vulnerability vulnerability = null; +424 if (null != dependency) { +425 final String version = nextLine.substring(VERSION.length()); +426 dependency.getVersionEvidence().addEvidence( +427 "bundler-audit", +428 "Version", +429 version, +430 Confidence.HIGHEST); +431 vulnerability = new Vulnerability(); // don't add to dependency until we have name set later +432 vulnerability.setMatchedCPE( +433 String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version), +434 null); +435 vulnerability.setCvssAccessVector("-"); +436 vulnerability.setCvssAccessComplexity("-"); +437 vulnerability.setCvssAuthentication("-"); +438 vulnerability.setCvssAvailabilityImpact("-"); +439 vulnerability.setCvssConfidentialityImpact("-"); +440 vulnerability.setCvssIntegrityImpact("-"); +441 } +442 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +443 return vulnerability; +444 } +445 +446 /** +447 * Creates the dependency based off of the gem. +448 * +449 * @param engine the engine used for scanning +450 * @param parentName the gem parent +451 * @param fileName the file name +452 * @param filePath the file path +453 * @param gem the gem name +454 * @return the dependency to add +455 * @throws IOException thrown if a temporary gem file could not be written +456 */ +457 private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException { +458 final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock"); +459 gemFile.createNewFile(); +460 final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem); +461 +462 FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling +463 final Dependency dependency = new Dependency(gemFile); +464 dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST); +465 dependency.setDisplayFileName(displayFileName); +466 dependency.setFileName(fileName); +467 dependency.setFilePath(filePath); +468 engine.getDependencies().add(dependency); +469 return dependency; +470 } +471 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html new file mode 100644 index 000000000..127f09633 --- /dev/null +++ b/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html @@ -0,0 +1,152 @@ + + + +RubyBundlerAnalyzer xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +3    *
      +4    * Licensed under the Apache License, Version 2.0 (the "License");
      +5    * you may not use this file except in compliance with the License.
      +6    * You may obtain a copy of the License at
      +7    *
      +8    *     http://www.apache.org/licenses/LICENSE-2.0
      +9    *
      +10   * Unless required by applicable law or agreed to in writing, software
      +11   * distributed under the License is distributed on an "AS IS" BASIS,
      +12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      +13   * See the License for the specific language governing permissions and
      +14   * limitations under the License.
      +15   *
      +16   * Copyright (c) 2016 Bianca Jiang. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.analyzer;
      +19  
      +20  import java.io.File;
      +21  import java.io.FilenameFilter;
      +22  
      +23  import org.owasp.dependencycheck.Engine;
      +24  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      +25  import org.owasp.dependencycheck.dependency.Dependency;
      +26  
      +27  /**
      +28   * This analyzer accepts the fully resolved .gemspec created by the Ruby bundler
      +29   * (http://bundler.io) for better evidence results. It also tries to resolve the
      +30   * dependency packagePath to where the gem is actually installed. Then during {@link org.owasp.dependencycheck.analyzer.AnalysisPhase#PRE_FINDING_ANALYSIS}
      +31   * {@link DependencyBundlingAnalyzer} will merge two .gemspec dependencies
      +32   * together if <code>Dependency.getPackagePath()</code> are the same.
      +33   *
      +34   * Ruby bundler creates new .gemspec files under a folder called
      +35   * "specifications" at deploy time, in addition to the original .gemspec files
      +36   * from source. The bundler generated .gemspec files always contain fully
      +37   * resolved attributes thus provide more accurate evidences, whereas the
      +38   * original .gemspec from source often contain variables for attributes that
      +39   * can't be used for evidences.
      +40   *
      +41   * Note this analyzer share the same
      +42   * {@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_RUBY_GEMSPEC_ENABLED} as
      +43   * {@link RubyGemspecAnalyzer}, so it will enabled/disabled with
      +44   * {@link RubyGemspecAnalyzer}.
      +45   *
      +46   * @author Bianca Jiang (biancajiang@gmail.com)
      +47   */
      +48  @Experimental
      +49  public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
      +50  
      +51      /**
      +52       * The name of the analyzer.
      +53       */
      +54      private static final String ANALYZER_NAME = "Ruby Bundler Analyzer";
      +55  
      +56      /**
      +57       * Folder name that contains .gemspec files created by "bundle install"
      +58       */
      +59      private static final String SPECIFICATIONS = "specifications";
      +60  
      +61      /**
      +62       * Folder name that contains the gems by "bundle install"
      +63       */
      +64      private static final String GEMS = "gems";
      +65  
      +66      /**
      +67       * Returns the name of the analyzer.
      +68       *
      +69       * @return the name of the analyzer.
      +70       */
      +71      @Override
      +72      public String getName() {
      +73          return ANALYZER_NAME;
      +74      }
      +75  
      +76      /**
      +77       * Only accept *.gemspec files generated by "bundle install --deployment"
      +78       * under "specifications" folder.
      +79       *
      +80       * @param pathname the path name to test
      +81       * @return true if the analyzer can process the given file; otherwise false
      +82       */
      +83      @Override
      +84      public boolean accept(File pathname) {
      +85  
      +86          boolean accepted = super.accept(pathname);
      +87          if (accepted) {
      +88              final File parentDir = pathname.getParentFile();
      +89              accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
      +90          }
      +91  
      +92          return accepted;
      +93      }
      +94  
      +95      @Override
      +96      protected void analyzeFileType(Dependency dependency, Engine engine)
      +97              throws AnalysisException {
      +98          super.analyzeFileType(dependency, engine);
      +99  
      +100         //find the corresponding gem folder for this .gemspec stub by "bundle install --deployment"
      +101         final File gemspecFile = dependency.getActualFile();
      +102         final String gemFileName = gemspecFile.getName();
      +103         final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec"));
      +104         final File specificationsDir = gemspecFile.getParentFile();
      +105         if (specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
      +106             final File parentDir = specificationsDir.getParentFile();
      +107             if (parentDir != null && parentDir.exists()) {
      +108                 final File gemsDir = new File(parentDir, GEMS);
      +109                 if (gemsDir.exists()) {
      +110                     final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
      +111                         public boolean accept(File dir, String name) {
      +112                             return name.equals(gemName);
      +113                         }
      +114                     });
      +115 
      +116                     if (matchingFiles != null && matchingFiles.length > 0) {
      +117                         final String gemPath = matchingFiles[0].getAbsolutePath();
      +118                         if (dependency.getActualFilePath().equals(dependency.getFilePath())) {
      +119                             if (gemPath != null) {
      +120                                 dependency.setPackagePath(gemPath);
      +121                             }
      +122                         } else {
      +123                             //.gemspec's actualFilePath and filePath are different when it's from a compressed file
      +124                             //in which case actualFilePath is the temp directory used by decompression.
      +125                             //packagePath should use the filePath of the identified gem file in "gems" folder
      +126                             final File gemspecStub = new File(dependency.getFilePath());
      +127                             final File specDir = gemspecStub.getParentFile();
      +128                             if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
      +129                                 final File gemsDir2 = new File(specDir.getParentFile(), GEMS);
      +130                                 final File packageDir = new File(gemsDir2, gemName);
      +131                                 dependency.setPackagePath(packageDir.getAbsolutePath());
      +132                             }
      +133                         }
      +134                     }
      +135                 }
      +136             }
      +137         }
      +138     }
      +139 }
      +
      +
      + + + diff --git a/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html index e648568bb..df6c70dd1 100644 --- a/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html @@ -25,148 +25,231 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import org.apache.commons.io.FileUtils; -21 import org.owasp.dependencycheck.Engine; -22 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -23 import org.owasp.dependencycheck.dependency.Confidence; -24 import org.owasp.dependencycheck.dependency.Dependency; -25 import org.owasp.dependencycheck.dependency.EvidenceCollection; -26 import org.owasp.dependencycheck.utils.FileFilterBuilder; -27 import org.owasp.dependencycheck.utils.Settings; +20 import java.io.File; +21 import java.io.FileFilter; +22 import java.io.FilenameFilter; +23 import java.io.IOException; +24 import java.nio.charset.Charset; +25 import java.util.List; +26 import java.util.regex.Matcher; +27 import java.util.regex.Pattern; 28 -29 import java.io.FileFilter; -30 import java.io.IOException; -31 import java.util.regex.Matcher; -32 import java.util.regex.Pattern; -33 -34 /** -35 * Used to analyze Ruby Gem specifications and collect information that can be used to determine the associated CPE. Regular -36 * expressions are used to parse the well-defined Ruby syntax that forms the specification. -37 * -38 * @author Dale Visser -39 */ -40 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { -41 -42 /** -43 * The name of the analyzer. -44 */ -45 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer"; -46 -47 /** -48 * The phase that this analyzer is intended to run in. -49 */ -50 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -51 -52 private static final String GEMSPEC = "gemspec"; -53 -54 private static final FileFilter FILTER -55 = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); -56 -57 private static final String EMAIL = "email"; +29 import org.apache.commons.io.FileUtils; +30 import org.owasp.dependencycheck.Engine; +31 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +32 import org.owasp.dependencycheck.dependency.Confidence; +33 import org.owasp.dependencycheck.dependency.Dependency; +34 import org.owasp.dependencycheck.dependency.EvidenceCollection; +35 import org.owasp.dependencycheck.utils.FileFilterBuilder; +36 import org.owasp.dependencycheck.utils.Settings; +37 import org.slf4j.Logger; +38 import org.slf4j.LoggerFactory; +39 +40 /** +41 * Used to analyze Ruby Gem specifications and collect information that can be +42 * used to determine the associated CPE. Regular expressions are used to parse +43 * the well-defined Ruby syntax that forms the specification. +44 * +45 * @author Dale Visser +46 */ +47 @Experimental +48 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { +49 +50 /** +51 * The logger. +52 */ +53 private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class); +54 /** +55 * The name of the analyzer. +56 */ +57 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer"; 58 59 /** -60 * @return a filter that accepts files named Rakefile or matching the glob pattern, *.gemspec +60 * The phase that this analyzer is intended to run in. 61 */ -62 @Override -63 protected FileFilter getFileFilter() { -64 return FILTER; -65 } -66 -67 @Override -68 protected void initializeFileTypeAnalyzer() throws Exception { -69 // NO-OP -70 } -71 -72 /** -73 * Returns the name of the analyzer. -74 * -75 * @return the name of the analyzer. -76 */ -77 @Override -78 public String getName() { -79 return ANALYZER_NAME; -80 } +62 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +63 +64 /** +65 * The gemspec file extension. +66 */ +67 private static final String GEMSPEC = "gemspec"; +68 +69 /** +70 * The file filter containing the list of file extensions that can be +71 * analyzed. +72 */ +73 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build(); +74 //TODO: support Rakefile +75 //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); +76 +77 /** +78 * The name of the version file. +79 */ +80 private static final String VERSION_FILE_NAME = "VERSION"; 81 82 /** -83 * Returns the phase that the analyzer is intended to run in. -84 * -85 * @return the phase that the analyzer is intended to run in. -86 */ -87 @Override -88 public AnalysisPhase getAnalysisPhase() { -89 return ANALYSIS_PHASE; -90 } -91 -92 /** -93 * Returns the key used in the properties file to reference the analyzer's enabled property. -94 * -95 * @return the analyzer's enabled property setting key -96 */ -97 @Override -98 protected String getAnalyzerEnabledSettingKey() { -99 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; -100 } -101 -102 /** -103 * The capture group #1 is the block variable. -104 */ -105 private static final Pattern GEMSPEC_BLOCK_INIT -106 = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); -107 -108 @Override -109 protected void analyzeFileType(Dependency dependency, Engine engine) -110 throws AnalysisException { -111 String contents; -112 try { -113 contents = FileUtils.readFileToString(dependency.getActualFile()); -114 } catch (IOException e) { -115 throw new AnalysisException( -116 "Problem occurred while reading dependency file.", e); -117 } -118 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); -119 if (matcher.find()) { -120 contents = contents.substring(matcher.end()); -121 final String blockVariable = matcher.group(1); -122 final EvidenceCollection vendor = dependency.getVendorEvidence(); -123 addStringEvidence(vendor, contents, blockVariable, "author", Confidence.HIGHEST); -124 addListEvidence(vendor, contents, blockVariable, "authors", Confidence.HIGHEST); -125 final String email = addStringEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM); -126 if (email.isEmpty()) { -127 addListEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM); -128 } -129 addStringEvidence(vendor, contents, blockVariable, "homepage", Confidence.MEDIUM); -130 final EvidenceCollection product = dependency.getProductEvidence(); -131 final String name = addStringEvidence(product, contents, blockVariable, "name", Confidence.HIGHEST); -132 if (!name.isEmpty()) { -133 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); -134 } -135 addStringEvidence(product, contents, blockVariable, "summary", Confidence.LOW); -136 addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", Confidence.HIGHEST); -137 } -138 } -139 -140 private void addListEvidence(EvidenceCollection evidences, String contents, -141 String blockVariable, String field, Confidence confidence) { -142 final Matcher matcher = Pattern.compile( -143 String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents); -144 if (matcher.find()) { -145 final String value = matcher.group(1).replaceAll("['\"]", " ").trim(); -146 evidences.addEvidence(GEMSPEC, field, value, confidence); -147 } -148 } -149 -150 private String addStringEvidence(EvidenceCollection evidences, String contents, -151 String blockVariable, String field, Confidence confidence) { -152 final Matcher matcher = Pattern.compile( -153 String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents); -154 String value = ""; -155 if (matcher.find()) { -156 value = matcher.group(2); -157 evidences.addEvidence(GEMSPEC, field, value, confidence); -158 } -159 return value; -160 } -161 } +83 * @return a filter that accepts files matching the glob pattern, *.gemspec +84 */ +85 @Override +86 protected FileFilter getFileFilter() { +87 return FILTER; +88 } +89 +90 @Override +91 protected void initializeFileTypeAnalyzer() throws Exception { +92 // NO-OP +93 } +94 +95 /** +96 * Returns the name of the analyzer. +97 * +98 * @return the name of the analyzer. +99 */ +100 @Override +101 public String getName() { +102 return ANALYZER_NAME; +103 } +104 +105 /** +106 * Returns the phase that the analyzer is intended to run in. +107 * +108 * @return the phase that the analyzer is intended to run in. +109 */ +110 @Override +111 public AnalysisPhase getAnalysisPhase() { +112 return ANALYSIS_PHASE; +113 } +114 +115 /** +116 * Returns the key used in the properties file to reference the analyzer's +117 * enabled property. +118 * +119 * @return the analyzer's enabled property setting key +120 */ +121 @Override +122 protected String getAnalyzerEnabledSettingKey() { +123 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; +124 } +125 +126 /** +127 * The capture group #1 is the block variable. +128 */ +129 private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); +130 +131 @Override +132 protected void analyzeFileType(Dependency dependency, Engine engine) +133 throws AnalysisException { +134 String contents; +135 try { +136 contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset()); +137 } catch (IOException e) { +138 throw new AnalysisException( +139 "Problem occurred while reading dependency file.", e); +140 } +141 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); +142 if (matcher.find()) { +143 contents = contents.substring(matcher.end()); +144 final String blockVariable = matcher.group(1); +145 +146 final EvidenceCollection vendor = dependency.getVendorEvidence(); +147 final EvidenceCollection product = dependency.getProductEvidence(); +148 final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST); +149 if (!name.isEmpty()) { +150 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); +151 } +152 addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.LOW); +153 +154 addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST); +155 addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM); +156 addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST); +157 addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST); +158 +159 final String value = addStringEvidence(dependency.getVersionEvidence(), contents, +160 blockVariable, "version", "version", Confidence.HIGHEST); +161 if (value.length() < 1) { +162 addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence()); +163 } +164 } +165 +166 setPackagePath(dependency); +167 } +168 +169 /** +170 * Adds the specified evidence to the given evidence collection. +171 * +172 * @param evidences the collection to add the evidence to +173 * @param contents the evidence contents +174 * @param blockVariable the variable +175 * @param field the field +176 * @param fieldPattern the field pattern +177 * @param confidence the confidence of the evidence +178 * @return the evidence string value added +179 */ +180 private String addStringEvidence(EvidenceCollection evidences, String contents, +181 String blockVariable, String field, String fieldPattern, Confidence confidence) { +182 String value = ""; +183 +184 //capture array value between [ ] +185 final Matcher arrayMatcher = Pattern.compile( +186 String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); +187 if (arrayMatcher.find()) { +188 final String arrayValue = arrayMatcher.group(1); +189 value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes +190 } else { //capture single value between quotes +191 final Matcher matcher = Pattern.compile( +192 String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); +193 if (matcher.find()) { +194 value = matcher.group(2); +195 } +196 } +197 if (value.length() > 0) { +198 evidences.addEvidence(GEMSPEC, field, value, confidence); +199 } +200 +201 return value; +202 } +203 +204 /** +205 * Adds evidence from the version file. +206 * +207 * @param dependencyFile the dependency being analyzed +208 * @param versionEvidences the version evidence +209 */ +210 private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) { +211 final File parentDir = dependencyFile.getParentFile(); +212 if (parentDir != null) { +213 final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() { +214 public boolean accept(File dir, String name) { +215 return name.contains(VERSION_FILE_NAME); +216 } +217 }); +218 for (File f : matchingFiles) { +219 try { +220 final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset()); +221 if (lines.size() == 1) { //TODO other checking? +222 final String value = lines.get(0).trim(); +223 versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH); +224 } +225 } catch (IOException e) { +226 LOGGER.debug("Error reading gemspec", e); +227 } +228 } +229 } +230 } +231 +232 /** +233 * Sets the package path on the dependency. +234 * +235 * @param dep the dependency to alter +236 */ +237 private void setPackagePath(Dependency dep) { +238 final File file = new File(dep.getFilePath()); +239 final String parent = file.getParent(); +240 if (parent != null) { +241 dep.setPackagePath(parent); +242 } +243 } +244 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html b/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html index 9ff0fa0d1..a60690b90 100644 --- a/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html +++ b/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer.exception diff --git a/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html b/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html index 0416afff2..9b8409cbc 100644 --- a/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html +++ b/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer.exception diff --git a/xref/org/owasp/dependencycheck/analyzer/package-frame.html b/xref/org/owasp/dependencycheck/analyzer/package-frame.html index b61b55652..19d87aa02 100644 --- a/xref/org/owasp/dependencycheck/analyzer/package-frame.html +++ b/xref/org/owasp/dependencycheck/analyzer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer @@ -62,6 +62,9 @@
    249. DependencyBundlingAnalyzer +
    250. +
    251. + Experimental
    252. FalsePositiveAnalyzer @@ -107,6 +110,9 @@
    253. RubyBundleAuditAnalyzer +
    254. +
    255. + RubyBundlerAnalyzer
    256. RubyGemspecAnalyzer diff --git a/xref/org/owasp/dependencycheck/analyzer/package-summary.html b/xref/org/owasp/dependencycheck/analyzer/package-summary.html index a71547779..d5813d8dc 100644 --- a/xref/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/xref/org/owasp/dependencycheck/analyzer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer @@ -114,6 +114,11 @@
    257. + + + + + +
      DependencyBundlingAnalyzer
      + Experimental +
      @@ -189,6 +194,11 @@ RubyBundleAuditAnalyzer
      + RubyBundlerAnalyzer +
      diff --git a/xref/org/owasp/dependencycheck/ant/logging/package-frame.html b/xref/org/owasp/dependencycheck/ant/logging/package-frame.html index 2f438e787..b09187c37 100644 --- a/xref/org/owasp/dependencycheck/ant/logging/package-frame.html +++ b/xref/org/owasp/dependencycheck/ant/logging/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.ant.logging + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.ant.logging diff --git a/xref/org/owasp/dependencycheck/ant/logging/package-summary.html b/xref/org/owasp/dependencycheck/ant/logging/package-summary.html index 0939b8f5d..1d38c16a2 100644 --- a/xref/org/owasp/dependencycheck/ant/logging/package-summary.html +++ b/xref/org/owasp/dependencycheck/ant/logging/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.ant.logging + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.ant.logging diff --git a/xref/org/owasp/dependencycheck/data/central/package-frame.html b/xref/org/owasp/dependencycheck/data/central/package-frame.html index f3342a343..13d47f8df 100644 --- a/xref/org/owasp/dependencycheck/data/central/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/central/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.central diff --git a/xref/org/owasp/dependencycheck/data/central/package-summary.html b/xref/org/owasp/dependencycheck/data/central/package-summary.html index b4248e92c..44353200c 100644 --- a/xref/org/owasp/dependencycheck/data/central/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/central/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.central diff --git a/xref/org/owasp/dependencycheck/data/composer/package-frame.html b/xref/org/owasp/dependencycheck/data/composer/package-frame.html index d4a1d784a..c99a71c93 100644 --- a/xref/org/owasp/dependencycheck/data/composer/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/composer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.composer diff --git a/xref/org/owasp/dependencycheck/data/composer/package-summary.html b/xref/org/owasp/dependencycheck/data/composer/package-summary.html index 28057f2c1..ce7e04939 100644 --- a/xref/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/composer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.composer diff --git a/xref/org/owasp/dependencycheck/data/cpe/package-frame.html b/xref/org/owasp/dependencycheck/data/cpe/package-frame.html index 32901ea46..9e005080b 100644 --- a/xref/org/owasp/dependencycheck/data/cpe/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/xref/org/owasp/dependencycheck/data/cpe/package-summary.html b/xref/org/owasp/dependencycheck/data/cpe/package-summary.html index 33861c9b1..abeb8638c 100644 --- a/xref/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/xref/org/owasp/dependencycheck/data/cwe/package-frame.html b/xref/org/owasp/dependencycheck/data/cwe/package-frame.html index 8e0b5afe5..c022c3d52 100644 --- a/xref/org/owasp/dependencycheck/data/cwe/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/cwe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/xref/org/owasp/dependencycheck/data/cwe/package-summary.html b/xref/org/owasp/dependencycheck/data/cwe/package-summary.html index 679ca2f14..bc3afbb4d 100644 --- a/xref/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/xref/org/owasp/dependencycheck/data/lucene/package-frame.html b/xref/org/owasp/dependencycheck/data/lucene/package-frame.html index 97579b1d0..69e545e84 100644 --- a/xref/org/owasp/dependencycheck/data/lucene/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/lucene/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/xref/org/owasp/dependencycheck/data/lucene/package-summary.html b/xref/org/owasp/dependencycheck/data/lucene/package-summary.html index c4c847c77..b48168f23 100644 --- a/xref/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/xref/org/owasp/dependencycheck/data/nexus/package-frame.html b/xref/org/owasp/dependencycheck/data/nexus/package-frame.html index 477b2dcdb..91cc0d7e1 100644 --- a/xref/org/owasp/dependencycheck/data/nexus/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/nexus/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/xref/org/owasp/dependencycheck/data/nexus/package-summary.html b/xref/org/owasp/dependencycheck/data/nexus/package-summary.html index b4c4f90dc..5803397e0 100644 --- a/xref/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/xref/org/owasp/dependencycheck/data/nuget/package-frame.html b/xref/org/owasp/dependencycheck/data/nuget/package-frame.html index e31f1d89e..b62b38691 100644 --- a/xref/org/owasp/dependencycheck/data/nuget/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/nuget/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/xref/org/owasp/dependencycheck/data/nuget/package-summary.html b/xref/org/owasp/dependencycheck/data/nuget/package-summary.html index 75e39d3a5..80bf952de 100644 --- a/xref/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html b/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html index 4268d8f7f..c9c5d0eef 100644 --- a/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html +++ b/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html @@ -77,731 +77,786 @@ 69 private ResourceBundle statementBundle = null; 70 71 /** -72 * Creates a new CveDB object and opens the database connection. Note, the connection must be closed by the caller by calling -73 * the close method. -74 * -75 * @throws DatabaseException thrown if there is an exception opening the database. +72 * Creates a new CveDB object and opens the database +73 * connection. Note, the connection must be closed by the caller by calling +74 * the close method. ======= Does the underlying connection support batch +75 * operations? 76 */ -77 public CveDB() throws DatabaseException { -78 super(); -79 try { -80 open(); -81 try { -82 final String databaseProductName = conn.getMetaData().getDatabaseProductName(); -83 LOGGER.debug("Database dialect: {}", databaseProductName); -84 final Locale dbDialect = new Locale(databaseProductName); -85 statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect); -86 } catch (SQLException se) { -87 LOGGER.warn("Problem loading database specific dialect!", se); -88 statementBundle = ResourceBundle.getBundle("data/dbStatements"); -89 } -90 databaseProperties = new DatabaseProperties(this); -91 } catch (DatabaseException ex) { -92 throw ex; -93 } -94 } -95 -96 /** -97 * Returns the database connection. -98 * -99 * @return the database connection -100 */ -101 protected Connection getConnection() { -102 return conn; -103 } -104 -105 /** -106 * Opens the database connection. If the database does not exist, it will create a new one. -107 * -108 * @throws DatabaseException thrown if there is an error opening the database connection -109 */ -110 public final void open() throws DatabaseException { -111 if (!isOpen()) { -112 conn = ConnectionFactory.getConnection(); -113 } -114 } -115 -116 /** -117 * Closes the DB4O database. Close should be called on this object when it is done being used. -118 */ -119 public void close() { -120 if (conn != null) { -121 try { -122 conn.close(); -123 } catch (SQLException ex) { -124 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); -125 LOGGER.debug("", ex); -126 } catch (Throwable ex) { -127 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); -128 LOGGER.debug("", ex); -129 } -130 conn = null; -131 } -132 } -133 -134 /** -135 * Returns whether the database connection is open or closed. -136 * -137 * @return whether the database connection is open or closed -138 */ -139 public boolean isOpen() { -140 return conn != null; -141 } -142 -143 /** -144 * Commits all completed transactions. -145 * -146 * @throws SQLException thrown if a SQL Exception occurs -147 */ -148 public void commit() throws SQLException { -149 //temporary remove this as autocommit is on. -150 //if (conn != null) { -151 // conn.commit(); -152 //} -153 } -154 -155 /** -156 * Cleans up the object and ensures that "close" has been called. -157 * -158 * @throws Throwable thrown if there is a problem -159 */ -160 @Override -161 @SuppressWarnings("FinalizeDeclaration") -162 protected void finalize() throws Throwable { -163 LOGGER.debug("Entering finalize"); -164 close(); -165 super.finalize(); +77 private boolean batchSupported; +78 +79 /** +80 * Creates a new CveDB object and opens the database connection. Note, the +81 * connection must be closed by the caller by calling the close method. +82 * +83 * @throws DatabaseException thrown if there is an exception opening the +84 * database. +85 */ +86 public CveDB() throws DatabaseException { +87 super(); +88 try { +89 open(); +90 try { +91 final String databaseProductName = conn.getMetaData().getDatabaseProductName(); +92 batchSupported = conn.getMetaData().supportsBatchUpdates(); +93 LOGGER.debug("Database dialect: {}", databaseProductName); +94 final Locale dbDialect = new Locale(databaseProductName); +95 statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect); +96 } catch (SQLException se) { +97 LOGGER.warn("Problem loading database specific dialect!", se); +98 statementBundle = ResourceBundle.getBundle("data/dbStatements"); +99 } +100 databaseProperties = new DatabaseProperties(this); +101 } catch (DatabaseException ex) { +102 throw ex; +103 } +104 } +105 +106 /** +107 * Returns the database connection. +108 * +109 * @return the database connection +110 */ +111 protected Connection getConnection() { +112 return conn; +113 } +114 +115 /** +116 * Opens the database connection. If the database does not exist, it will +117 * create a new one. +118 * +119 * @throws DatabaseException thrown if there is an error opening the +120 * database connection +121 */ +122 public final void open() throws DatabaseException { +123 if (!isOpen()) { +124 conn = ConnectionFactory.getConnection(); +125 } +126 } +127 +128 /** +129 * Closes the DB4O database. Close should be called on this object when it +130 * is done being used. +131 */ +132 public void close() { +133 if (conn != null) { +134 try { +135 conn.close(); +136 } catch (SQLException ex) { +137 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); +138 LOGGER.debug("", ex); +139 } catch (Throwable ex) { +140 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); +141 LOGGER.debug("", ex); +142 } +143 conn = null; +144 } +145 } +146 +147 /** +148 * Returns whether the database connection is open or closed. +149 * +150 * @return whether the database connection is open or closed +151 */ +152 public boolean isOpen() { +153 return conn != null; +154 } +155 +156 /** +157 * Commits all completed transactions. +158 * +159 * @throws SQLException thrown if a SQL Exception occurs +160 */ +161 public void commit() throws SQLException { +162 //temporary remove this as autocommit is on. +163 //if (conn != null) { +164 // conn.commit(); +165 //} 166 } -167 /** -168 * Database properties object containing the 'properties' from the database table. -169 */ -170 private DatabaseProperties databaseProperties; -171 -172 /** -173 * Get the value of databaseProperties. -174 * -175 * @return the value of databaseProperties -176 */ -177 public DatabaseProperties getDatabaseProperties() { -178 return databaseProperties; +167 +168 /** +169 * Cleans up the object and ensures that "close" has been called. +170 * +171 * @throws Throwable thrown if there is a problem +172 */ +173 @Override +174 @SuppressWarnings("FinalizeDeclaration") +175 protected void finalize() throws Throwable { +176 LOGGER.debug("Entering finalize"); +177 close(); +178 super.finalize(); 179 } -180 -181 /** -182 * Searches the CPE entries in the database and retrieves all entries for a given vendor and product combination. The returned -183 * list will include all versions of the product that are registered in the NVD CVE data. -184 * -185 * @param vendor the identified vendor name of the dependency being analyzed -186 * @param product the identified name of the product of the dependency being analyzed -187 * @return a set of vulnerable software -188 */ -189 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { -190 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); -191 ResultSet rs = null; -192 PreparedStatement ps = null; -193 try { -194 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); -195 ps.setString(1, vendor); -196 ps.setString(2, product); -197 rs = ps.executeQuery(); -198 -199 while (rs.next()) { -200 final VulnerableSoftware vs = new VulnerableSoftware(); -201 vs.setCpe(rs.getString(1)); -202 cpe.add(vs); -203 } -204 } catch (SQLException ex) { -205 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -206 LOGGER.debug("", ex); -207 } finally { -208 DBUtils.closeResultSet(rs); -209 DBUtils.closeStatement(ps); -210 } -211 return cpe; -212 } -213 -214 /** -215 * Returns the entire list of vendor/product combinations. -216 * -217 * @return the entire list of vendor/product combinations -218 * @throws DatabaseException thrown when there is an error retrieving the data from the DB -219 */ -220 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { -221 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); -222 ResultSet rs = null; -223 PreparedStatement ps = null; -224 try { -225 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); -226 rs = ps.executeQuery(); -227 while (rs.next()) { -228 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); -229 } -230 } catch (SQLException ex) { -231 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; -232 throw new DatabaseException(msg, ex); -233 } finally { -234 DBUtils.closeResultSet(rs); -235 DBUtils.closeStatement(ps); -236 } -237 return data; -238 } -239 -240 /** -241 * Returns a set of properties. -242 * -243 * @return the properties from the database -244 */ -245 Properties getProperties() { -246 final Properties prop = new Properties(); -247 PreparedStatement ps = null; -248 ResultSet rs = null; -249 try { -250 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); -251 rs = ps.executeQuery(); -252 while (rs.next()) { -253 prop.setProperty(rs.getString(1), rs.getString(2)); -254 } -255 } catch (SQLException ex) { -256 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -257 LOGGER.debug("", ex); -258 } finally { -259 DBUtils.closeStatement(ps); -260 DBUtils.closeResultSet(rs); -261 } -262 return prop; -263 } -264 -265 /** -266 * Saves a property to the database. -267 * -268 * @param key the property key -269 * @param value the property value -270 */ -271 void saveProperty(String key, String value) { -272 try { -273 try { -274 final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY")); -275 try { -276 mergeProperty.setString(1, key); -277 mergeProperty.setString(2, value); -278 mergeProperty.executeUpdate(); -279 } finally { -280 DBUtils.closeStatement(mergeProperty); -281 } -282 } catch (MissingResourceException mre) { -283 // No Merge statement, so doing an Update/Insert... -284 PreparedStatement updateProperty = null; -285 PreparedStatement insertProperty = null; -286 try { -287 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); -288 updateProperty.setString(1, value); -289 updateProperty.setString(2, key); -290 if (updateProperty.executeUpdate() == 0) { -291 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); -292 insertProperty.setString(1, key); -293 insertProperty.setString(2, value); -294 insertProperty.executeUpdate(); -295 } +180 /** +181 * Database properties object containing the 'properties' from the database +182 * table. +183 */ +184 private DatabaseProperties databaseProperties; +185 +186 /** +187 * Get the value of databaseProperties. +188 * +189 * @return the value of databaseProperties +190 */ +191 public DatabaseProperties getDatabaseProperties() { +192 return databaseProperties; +193 } +194 +195 /** +196 * Searches the CPE entries in the database and retrieves all entries for a +197 * given vendor and product combination. The returned list will include all +198 * versions of the product that are registered in the NVD CVE data. +199 * +200 * @param vendor the identified vendor name of the dependency being analyzed +201 * @param product the identified name of the product of the dependency being +202 * analyzed +203 * @return a set of vulnerable software +204 */ +205 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { +206 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); +207 ResultSet rs = null; +208 PreparedStatement ps = null; +209 try { +210 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); +211 ps.setString(1, vendor); +212 ps.setString(2, product); +213 rs = ps.executeQuery(); +214 +215 while (rs.next()) { +216 final VulnerableSoftware vs = new VulnerableSoftware(); +217 vs.setCpe(rs.getString(1)); +218 cpe.add(vs); +219 } +220 } catch (SQLException ex) { +221 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +222 LOGGER.debug("", ex); +223 } finally { +224 DBUtils.closeResultSet(rs); +225 DBUtils.closeStatement(ps); +226 } +227 return cpe; +228 } +229 +230 /** +231 * Returns the entire list of vendor/product combinations. +232 * +233 * @return the entire list of vendor/product combinations +234 * @throws DatabaseException thrown when there is an error retrieving the +235 * data from the DB +236 */ +237 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { +238 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); +239 ResultSet rs = null; +240 PreparedStatement ps = null; +241 try { +242 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); +243 rs = ps.executeQuery(); +244 while (rs.next()) { +245 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); +246 } +247 } catch (SQLException ex) { +248 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; +249 throw new DatabaseException(msg, ex); +250 } finally { +251 DBUtils.closeResultSet(rs); +252 DBUtils.closeStatement(ps); +253 } +254 return data; +255 } +256 +257 /** +258 * Returns a set of properties. +259 * +260 * @return the properties from the database +261 */ +262 Properties getProperties() { +263 final Properties prop = new Properties(); +264 PreparedStatement ps = null; +265 ResultSet rs = null; +266 try { +267 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); +268 rs = ps.executeQuery(); +269 while (rs.next()) { +270 prop.setProperty(rs.getString(1), rs.getString(2)); +271 } +272 } catch (SQLException ex) { +273 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +274 LOGGER.debug("", ex); +275 } finally { +276 DBUtils.closeStatement(ps); +277 DBUtils.closeResultSet(rs); +278 } +279 return prop; +280 } +281 +282 /** +283 * Saves a property to the database. +284 * +285 * @param key the property key +286 * @param value the property value +287 */ +288 void saveProperty(String key, String value) { +289 try { +290 try { +291 final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY")); +292 try { +293 mergeProperty.setString(1, key); +294 mergeProperty.setString(2, value); +295 mergeProperty.executeUpdate(); 296 } finally { -297 DBUtils.closeStatement(updateProperty); -298 DBUtils.closeStatement(insertProperty); -299 } -300 } -301 } catch (SQLException ex) { -302 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); -303 LOGGER.debug("", ex); -304 } -305 } -306 -307 /** -308 * Retrieves the vulnerabilities associated with the specified CPE. -309 * -310 * @param cpeStr the CPE name -311 * @return a list of Vulnerabilities -312 * @throws DatabaseException thrown if there is an exception retrieving data -313 */ -314 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { -315 final VulnerableSoftware cpe = new VulnerableSoftware(); -316 try { -317 cpe.parseName(cpeStr); -318 } catch (UnsupportedEncodingException ex) { -319 LOGGER.trace("", ex); -320 } -321 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); -322 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); +297 DBUtils.closeStatement(mergeProperty); +298 } +299 } catch (MissingResourceException mre) { +300 // No Merge statement, so doing an Update/Insert... +301 PreparedStatement updateProperty = null; +302 PreparedStatement insertProperty = null; +303 try { +304 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); +305 updateProperty.setString(1, value); +306 updateProperty.setString(2, key); +307 if (updateProperty.executeUpdate() == 0) { +308 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); +309 insertProperty.setString(1, key); +310 insertProperty.setString(2, value); +311 insertProperty.executeUpdate(); +312 } +313 } finally { +314 DBUtils.closeStatement(updateProperty); +315 DBUtils.closeStatement(insertProperty); +316 } +317 } +318 } catch (SQLException ex) { +319 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); +320 LOGGER.debug("", ex); +321 } +322 } 323 -324 PreparedStatement ps = null; -325 ResultSet rs = null; -326 try { -327 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); -328 ps.setString(1, cpe.getVendor()); -329 ps.setString(2, cpe.getProduct()); -330 rs = ps.executeQuery(); -331 String currentCVE = ""; -332 -333 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); -334 while (rs.next()) { -335 final String cveId = rs.getString(1); -336 if (!currentCVE.equals(cveId)) { //check for match and add -337 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); -338 if (matchedCPE != null) { -339 final Vulnerability v = getVulnerability(currentCVE); -340 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); -341 vulnerabilities.add(v); -342 } -343 vulnSoftware.clear(); -344 currentCVE = cveId; -345 } -346 -347 final String cpeId = rs.getString(2); -348 final String previous = rs.getString(3); -349 final Boolean p = previous != null && !previous.isEmpty(); -350 vulnSoftware.put(cpeId, p); -351 } -352 //remember to process the last set of CVE/CPE entries -353 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); -354 if (matchedCPE != null) { -355 final Vulnerability v = getVulnerability(currentCVE); -356 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); -357 vulnerabilities.add(v); -358 } -359 } catch (SQLException ex) { -360 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); -361 } finally { -362 DBUtils.closeResultSet(rs); -363 DBUtils.closeStatement(ps); -364 } -365 return vulnerabilities; -366 } -367 -368 /** -369 * Gets a vulnerability for the provided CVE. -370 * -371 * @param cve the CVE to lookup -372 * @return a vulnerability object -373 * @throws DatabaseException if an exception occurs -374 */ -375 private Vulnerability getVulnerability(String cve) throws DatabaseException { -376 PreparedStatement psV = null; -377 PreparedStatement psR = null; -378 PreparedStatement psS = null; -379 ResultSet rsV = null; -380 ResultSet rsR = null; -381 ResultSet rsS = null; -382 Vulnerability vuln = null; -383 try { -384 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); -385 psV.setString(1, cve); -386 rsV = psV.executeQuery(); -387 if (rsV.next()) { -388 vuln = new Vulnerability(); -389 vuln.setName(cve); -390 vuln.setDescription(rsV.getString(2)); -391 String cwe = rsV.getString(3); -392 if (cwe != null) { -393 final String name = CweDB.getCweName(cwe); -394 if (name != null) { -395 cwe += ' ' + name; -396 } -397 } -398 final int cveId = rsV.getInt(1); -399 vuln.setCwe(cwe); -400 vuln.setCvssScore(rsV.getFloat(4)); -401 vuln.setCvssAccessVector(rsV.getString(5)); -402 vuln.setCvssAccessComplexity(rsV.getString(6)); -403 vuln.setCvssAuthentication(rsV.getString(7)); -404 vuln.setCvssConfidentialityImpact(rsV.getString(8)); -405 vuln.setCvssIntegrityImpact(rsV.getString(9)); -406 vuln.setCvssAvailabilityImpact(rsV.getString(10)); -407 -408 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); -409 psR.setInt(1, cveId); -410 rsR = psR.executeQuery(); -411 while (rsR.next()) { -412 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); -413 } -414 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); -415 psS.setInt(1, cveId); -416 rsS = psS.executeQuery(); -417 while (rsS.next()) { -418 final String cpe = rsS.getString(1); -419 final String prevVersion = rsS.getString(2); -420 if (prevVersion == null) { -421 vuln.addVulnerableSoftware(cpe); -422 } else { -423 vuln.addVulnerableSoftware(cpe, prevVersion); -424 } -425 } -426 } -427 } catch (SQLException ex) { -428 throw new DatabaseException("Error retrieving " + cve, ex); -429 } finally { -430 DBUtils.closeResultSet(rsV); -431 DBUtils.closeResultSet(rsR); -432 DBUtils.closeResultSet(rsS); -433 DBUtils.closeStatement(psV); -434 DBUtils.closeStatement(psR); -435 DBUtils.closeStatement(psS); -436 } -437 return vuln; -438 } -439 -440 /** -441 * Updates the vulnerability within the database. If the vulnerability does not exist it will be added. -442 * -443 * @param vuln the vulnerability to add to the database -444 * @throws DatabaseException is thrown if the database -445 */ -446 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { -447 PreparedStatement selectVulnerabilityId = null; -448 PreparedStatement deleteVulnerability = null; -449 PreparedStatement deleteReferences = null; -450 PreparedStatement deleteSoftware = null; -451 PreparedStatement updateVulnerability = null; -452 PreparedStatement insertVulnerability = null; -453 PreparedStatement insertReference = null; -454 PreparedStatement selectCpeId = null; -455 PreparedStatement insertCpe = null; -456 PreparedStatement insertSoftware = null; +324 /** +325 * Retrieves the vulnerabilities associated with the specified CPE. +326 * +327 * @param cpeStr the CPE name +328 * @return a list of Vulnerabilities +329 * @throws DatabaseException thrown if there is an exception retrieving data +330 */ +331 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { +332 final VulnerableSoftware cpe = new VulnerableSoftware(); +333 try { +334 cpe.parseName(cpeStr); +335 } catch (UnsupportedEncodingException ex) { +336 LOGGER.trace("", ex); +337 } +338 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); +339 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); +340 +341 PreparedStatement ps = null; +342 ResultSet rs = null; +343 try { +344 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); +345 ps.setString(1, cpe.getVendor()); +346 ps.setString(2, cpe.getProduct()); +347 rs = ps.executeQuery(); +348 String currentCVE = ""; +349 +350 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); +351 while (rs.next()) { +352 final String cveId = rs.getString(1); +353 if (!currentCVE.equals(cveId)) { //check for match and add +354 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +355 if (matchedCPE != null) { +356 final Vulnerability v = getVulnerability(currentCVE); +357 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +358 vulnerabilities.add(v); +359 } +360 vulnSoftware.clear(); +361 currentCVE = cveId; +362 } +363 +364 final String cpeId = rs.getString(2); +365 final String previous = rs.getString(3); +366 final Boolean p = previous != null && !previous.isEmpty(); +367 vulnSoftware.put(cpeId, p); +368 } +369 //remember to process the last set of CVE/CPE entries +370 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +371 if (matchedCPE != null) { +372 final Vulnerability v = getVulnerability(currentCVE); +373 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +374 vulnerabilities.add(v); +375 } +376 } catch (SQLException ex) { +377 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); +378 } finally { +379 DBUtils.closeResultSet(rs); +380 DBUtils.closeStatement(ps); +381 } +382 return vulnerabilities; +383 } +384 +385 /** +386 * Gets a vulnerability for the provided CVE. +387 * +388 * @param cve the CVE to lookup +389 * @return a vulnerability object +390 * @throws DatabaseException if an exception occurs +391 */ +392 public Vulnerability getVulnerability(String cve) throws DatabaseException { +393 PreparedStatement psV = null; +394 PreparedStatement psR = null; +395 PreparedStatement psS = null; +396 ResultSet rsV = null; +397 ResultSet rsR = null; +398 ResultSet rsS = null; +399 Vulnerability vuln = null; +400 +401 try { +402 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); +403 psV.setString(1, cve); +404 rsV = psV.executeQuery(); +405 if (rsV.next()) { +406 vuln = new Vulnerability(); +407 vuln.setName(cve); +408 vuln.setDescription(rsV.getString(2)); +409 String cwe = rsV.getString(3); +410 if (cwe != null) { +411 final String name = CweDB.getCweName(cwe); +412 if (name != null) { +413 cwe += ' ' + name; +414 } +415 } +416 final int cveId = rsV.getInt(1); +417 vuln.setCwe(cwe); +418 vuln.setCvssScore(rsV.getFloat(4)); +419 vuln.setCvssAccessVector(rsV.getString(5)); +420 vuln.setCvssAccessComplexity(rsV.getString(6)); +421 vuln.setCvssAuthentication(rsV.getString(7)); +422 vuln.setCvssConfidentialityImpact(rsV.getString(8)); +423 vuln.setCvssIntegrityImpact(rsV.getString(9)); +424 vuln.setCvssAvailabilityImpact(rsV.getString(10)); +425 +426 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); +427 psR.setInt(1, cveId); +428 rsR = psR.executeQuery(); +429 while (rsR.next()) { +430 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); +431 } +432 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); +433 psS.setInt(1, cveId); +434 rsS = psS.executeQuery(); +435 while (rsS.next()) { +436 final String cpe = rsS.getString(1); +437 final String prevVersion = rsS.getString(2); +438 if (prevVersion == null) { +439 vuln.addVulnerableSoftware(cpe); +440 } else { +441 vuln.addVulnerableSoftware(cpe, prevVersion); +442 } +443 } +444 } +445 } catch (SQLException ex) { +446 throw new DatabaseException("Error retrieving " + cve, ex); +447 } finally { +448 DBUtils.closeResultSet(rsV); +449 DBUtils.closeResultSet(rsR); +450 DBUtils.closeResultSet(rsS); +451 DBUtils.closeStatement(psV); +452 DBUtils.closeStatement(psR); +453 DBUtils.closeStatement(psS); +454 } +455 return vuln; +456 } 457 -458 try { -459 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); -460 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); -461 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); -462 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); -463 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); -464 final String[] ids = {"id"}; -465 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), -466 //Statement.RETURN_GENERATED_KEYS); -467 ids); -468 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); -469 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); -470 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), -471 //Statement.RETURN_GENERATED_KEYS); -472 ids); -473 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); -474 int vulnerabilityId = 0; -475 selectVulnerabilityId.setString(1, vuln.getName()); -476 ResultSet rs = selectVulnerabilityId.executeQuery(); -477 if (rs.next()) { -478 vulnerabilityId = rs.getInt(1); -479 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. -480 deleteReferences.setInt(1, vulnerabilityId); -481 deleteReferences.execute(); -482 deleteSoftware.setInt(1, vulnerabilityId); -483 deleteSoftware.execute(); -484 } -485 DBUtils.closeResultSet(rs); -486 rs = null; -487 if (vulnerabilityId != 0) { -488 if (vuln.getDescription().contains("** REJECT **")) { -489 deleteVulnerability.setInt(1, vulnerabilityId); -490 deleteVulnerability.executeUpdate(); -491 } else { -492 updateVulnerability.setString(1, vuln.getDescription()); -493 updateVulnerability.setString(2, vuln.getCwe()); -494 updateVulnerability.setFloat(3, vuln.getCvssScore()); -495 updateVulnerability.setString(4, vuln.getCvssAccessVector()); -496 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); -497 updateVulnerability.setString(6, vuln.getCvssAuthentication()); -498 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); -499 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); -500 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); -501 updateVulnerability.setInt(10, vulnerabilityId); -502 updateVulnerability.executeUpdate(); -503 } -504 } else { -505 insertVulnerability.setString(1, vuln.getName()); -506 insertVulnerability.setString(2, vuln.getDescription()); -507 insertVulnerability.setString(3, vuln.getCwe()); -508 insertVulnerability.setFloat(4, vuln.getCvssScore()); -509 insertVulnerability.setString(5, vuln.getCvssAccessVector()); -510 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); -511 insertVulnerability.setString(7, vuln.getCvssAuthentication()); -512 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); -513 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); -514 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); -515 insertVulnerability.execute(); -516 try { -517 rs = insertVulnerability.getGeneratedKeys(); -518 rs.next(); -519 vulnerabilityId = rs.getInt(1); -520 } catch (SQLException ex) { -521 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); -522 throw new DatabaseException(msg, ex); -523 } finally { -524 DBUtils.closeResultSet(rs); -525 rs = null; -526 } -527 } -528 insertReference.setInt(1, vulnerabilityId); -529 for (Reference r : vuln.getReferences()) { -530 insertReference.setString(2, r.getName()); -531 insertReference.setString(3, r.getUrl()); -532 insertReference.setString(4, r.getSource()); -533 insertReference.execute(); -534 } -535 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { -536 int cpeProductId = 0; -537 selectCpeId.setString(1, s.getName()); -538 try { -539 rs = selectCpeId.executeQuery(); -540 if (rs.next()) { -541 cpeProductId = rs.getInt(1); -542 } -543 } catch (SQLException ex) { -544 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex); -545 } finally { -546 DBUtils.closeResultSet(rs); -547 rs = null; -548 } -549 -550 if (cpeProductId == 0) { -551 insertCpe.setString(1, s.getName()); -552 insertCpe.setString(2, s.getVendor()); -553 insertCpe.setString(3, s.getProduct()); -554 insertCpe.executeUpdate(); -555 cpeProductId = DBUtils.getGeneratedKey(insertCpe); -556 } -557 if (cpeProductId == 0) { -558 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned"); +458 /** +459 * Updates the vulnerability within the database. If the vulnerability does +460 * not exist it will be added. +461 * +462 * @param vuln the vulnerability to add to the database +463 * @throws DatabaseException is thrown if the database +464 */ +465 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { +466 PreparedStatement selectVulnerabilityId = null; +467 PreparedStatement deleteVulnerability = null; +468 PreparedStatement deleteReferences = null; +469 PreparedStatement deleteSoftware = null; +470 PreparedStatement updateVulnerability = null; +471 PreparedStatement insertVulnerability = null; +472 PreparedStatement insertReference = null; +473 PreparedStatement selectCpeId = null; +474 PreparedStatement insertCpe = null; +475 PreparedStatement insertSoftware = null; +476 +477 try { +478 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); +479 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); +480 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); +481 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); +482 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); +483 final String[] ids = {"id"}; +484 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), +485 //Statement.RETURN_GENERATED_KEYS); +486 ids); +487 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); +488 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); +489 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), +490 //Statement.RETURN_GENERATED_KEYS); +491 ids); +492 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); +493 int vulnerabilityId = 0; +494 selectVulnerabilityId.setString(1, vuln.getName()); +495 ResultSet rs = selectVulnerabilityId.executeQuery(); +496 if (rs.next()) { +497 vulnerabilityId = rs.getInt(1); +498 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. +499 deleteReferences.setInt(1, vulnerabilityId); +500 deleteReferences.execute(); +501 deleteSoftware.setInt(1, vulnerabilityId); +502 deleteSoftware.execute(); +503 } +504 DBUtils.closeResultSet(rs); +505 rs = null; +506 +507 if (vulnerabilityId != 0) { +508 if (vuln.getDescription().contains("** REJECT **")) { +509 deleteVulnerability.setInt(1, vulnerabilityId); +510 deleteVulnerability.executeUpdate(); +511 } else { +512 updateVulnerability.setString(1, vuln.getDescription()); +513 updateVulnerability.setString(2, vuln.getCwe()); +514 updateVulnerability.setFloat(3, vuln.getCvssScore()); +515 updateVulnerability.setString(4, vuln.getCvssAccessVector()); +516 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); +517 updateVulnerability.setString(6, vuln.getCvssAuthentication()); +518 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); +519 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); +520 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); +521 updateVulnerability.setInt(10, vulnerabilityId); +522 updateVulnerability.executeUpdate(); +523 } +524 } else { +525 insertVulnerability.setString(1, vuln.getName()); +526 insertVulnerability.setString(2, vuln.getDescription()); +527 insertVulnerability.setString(3, vuln.getCwe()); +528 insertVulnerability.setFloat(4, vuln.getCvssScore()); +529 insertVulnerability.setString(5, vuln.getCvssAccessVector()); +530 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); +531 insertVulnerability.setString(7, vuln.getCvssAuthentication()); +532 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); +533 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); +534 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); +535 insertVulnerability.execute(); +536 try { +537 rs = insertVulnerability.getGeneratedKeys(); +538 rs.next(); +539 vulnerabilityId = rs.getInt(1); +540 } catch (SQLException ex) { +541 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); +542 throw new DatabaseException(msg, ex); +543 } finally { +544 DBUtils.closeResultSet(rs); +545 rs = null; +546 } +547 } +548 +549 for (Reference r : vuln.getReferences()) { +550 insertReference.setInt(1, vulnerabilityId); +551 insertReference.setString(2, r.getName()); +552 insertReference.setString(3, r.getUrl()); +553 insertReference.setString(4, r.getSource()); +554 +555 if (batchSupported) { +556 insertReference.addBatch(); +557 } else { +558 insertReference.execute(); 559 } -560 -561 insertSoftware.setInt(1, vulnerabilityId); -562 insertSoftware.setInt(2, cpeProductId); -563 if (s.getPreviousVersion() == null) { -564 insertSoftware.setNull(3, java.sql.Types.VARCHAR); -565 } else { -566 insertSoftware.setString(3, s.getPreviousVersion()); -567 } -568 insertSoftware.execute(); -569 } -570 -571 } catch (SQLException ex) { -572 final String msg = String.format("Error updating '%s'", vuln.getName()); -573 LOGGER.debug("", ex); -574 throw new DatabaseException(msg, ex); -575 } finally { -576 DBUtils.closeStatement(selectVulnerabilityId); -577 DBUtils.closeStatement(deleteReferences); -578 DBUtils.closeStatement(deleteSoftware); -579 DBUtils.closeStatement(updateVulnerability); -580 DBUtils.closeStatement(deleteVulnerability); -581 DBUtils.closeStatement(insertVulnerability); -582 DBUtils.closeStatement(insertReference); -583 DBUtils.closeStatement(selectCpeId); -584 DBUtils.closeStatement(insertCpe); -585 DBUtils.closeStatement(insertSoftware); -586 } -587 } -588 -589 /** -590 * Checks to see if data exists so that analysis can be performed. -591 * -592 * @return <code>true</code> if data exists; otherwise <code>false</code> -593 */ -594 public boolean dataExists() { -595 Statement cs = null; -596 ResultSet rs = null; -597 try { -598 cs = conn.createStatement(); -599 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); -600 if (rs.next()) { -601 if (rs.getInt(1) > 0) { -602 return true; -603 } -604 } -605 } catch (SQLException ex) { -606 String dd; -607 try { -608 dd = Settings.getDataDirectory().getAbsolutePath(); -609 } catch (IOException ex1) { -610 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -611 } -612 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. " -613 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please " -614 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " -615 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n", -616 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); -617 LOGGER.debug("", ex); -618 } finally { -619 DBUtils.closeResultSet(rs); -620 DBUtils.closeStatement(cs); -621 } -622 return false; -623 } -624 -625 /** -626 * It is possible that orphaned rows may be generated during database updates. This should be called after all updates have -627 * been completed to ensure orphan entries are removed. -628 */ -629 public void cleanupDatabase() { -630 PreparedStatement ps = null; -631 try { -632 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); -633 if (ps != null) { -634 ps.executeUpdate(); -635 } -636 } catch (SQLException ex) { -637 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -638 LOGGER.debug("", ex); -639 } finally { -640 DBUtils.closeStatement(ps); -641 } -642 } -643 -644 /** -645 * Determines if the given identifiedVersion is affected by the given cpeId and previous version flag. A non-null, non-empty -646 * string passed to the previous version argument indicates that all previous versions are affected. -647 * -648 * @param vendor the vendor of the dependency being analyzed -649 * @param product the product name of the dependency being analyzed -650 * @param vulnerableSoftware a map of the vulnerable software with a boolean indicating if all previous versions are affected -651 * @param identifiedVersion the identified version of the dependency being analyzed -652 * @return true if the identified version is affected, otherwise false -653 */ -654 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, -655 DependencyVersion identifiedVersion) { -656 -657 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); -658 -659 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); -660 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); -661 String majorVersionMatch = null; -662 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -663 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -664 if (v == null || "-".equals(v.toString())) { //all versions -665 return entry; -666 } -667 if (entry.getValue()) { -668 if (matchesAnyPrevious) { -669 return entry; -670 } -671 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { -672 majorVersionMatch = v.getVersionParts().get(0); -673 } -674 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); -675 } -676 } -677 if (matchesAnyPrevious) { -678 return null; -679 } -680 -681 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; -682 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions -683 //then later we process those that affect all versions. This could be done with sorting... -684 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -685 if (!entry.getValue()) { -686 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -687 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -688 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -689 continue; -690 } -691 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -692 //in the above loop or just after loop (if matchesAnyPrevious return null). -693 if (identifiedVersion.equals(v)) { -694 return entry; -695 } -696 } -697 } -698 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -699 if (entry.getValue()) { -700 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -701 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -702 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -703 continue; -704 } -705 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -706 //in the above loop or just after loop (if matchesAnyPrevious return null). -707 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { -708 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { -709 return entry; -710 } -711 } -712 } -713 } -714 return null; -715 } -716 -717 /** -718 * Parses the version (including revision) from a CPE identifier. If no version is identified then a '-' is returned. -719 * -720 * @param cpeStr a cpe identifier -721 * @return a dependency version -722 */ -723 private DependencyVersion parseDependencyVersion(String cpeStr) { -724 final VulnerableSoftware cpe = new VulnerableSoftware(); -725 try { -726 cpe.parseName(cpeStr); -727 } catch (UnsupportedEncodingException ex) { -728 //never going to happen. -729 LOGGER.trace("", ex); -730 } -731 return parseDependencyVersion(cpe); -732 } -733 -734 /** -735 * Takes a CPE and parses out the version number. If no version is identified then a '-' is returned. -736 * -737 * @param cpe a cpe object -738 * @return a dependency version -739 */ -740 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { -741 final DependencyVersion cpeVersion; -742 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { -743 final String versionText; -744 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) { -745 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate()); -746 } else { -747 versionText = cpe.getVersion(); +560 } +561 +562 if (batchSupported) { +563 insertReference.executeBatch(); +564 } +565 +566 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { +567 int cpeProductId = 0; +568 selectCpeId.setString(1, s.getName()); +569 try { +570 rs = selectCpeId.executeQuery(); +571 if (rs.next()) { +572 cpeProductId = rs.getInt(1); +573 } +574 } catch (SQLException ex) { +575 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex); +576 } finally { +577 DBUtils.closeResultSet(rs); +578 rs = null; +579 } +580 +581 if (cpeProductId == 0) { +582 insertCpe.setString(1, s.getName()); +583 insertCpe.setString(2, s.getVendor()); +584 insertCpe.setString(3, s.getProduct()); +585 insertCpe.executeUpdate(); +586 cpeProductId = DBUtils.getGeneratedKey(insertCpe); +587 } +588 if (cpeProductId == 0) { +589 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned"); +590 } +591 +592 insertSoftware.setInt(1, vulnerabilityId); +593 insertSoftware.setInt(2, cpeProductId); +594 +595 if (s.getPreviousVersion() == null) { +596 insertSoftware.setNull(3, java.sql.Types.VARCHAR); +597 } else { +598 insertSoftware.setString(3, s.getPreviousVersion()); +599 } +600 if (batchSupported) { +601 insertSoftware.addBatch(); +602 } else { +603 try { +604 insertSoftware.execute(); +605 } catch (SQLException ex) { +606 if (ex.getMessage().contains("Duplicate entry")) { +607 final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName()); +608 LOGGER.debug(msg, ex); +609 } else { +610 throw ex; +611 } +612 } +613 } +614 } +615 if (batchSupported) { +616 insertSoftware.executeBatch(); +617 } +618 } catch (SQLException ex) { +619 final String msg = String.format("Error updating '%s'", vuln.getName()); +620 LOGGER.debug(msg, ex); +621 throw new DatabaseException(msg, ex); +622 } finally { +623 DBUtils.closeStatement(selectVulnerabilityId); +624 DBUtils.closeStatement(deleteReferences); +625 DBUtils.closeStatement(deleteSoftware); +626 DBUtils.closeStatement(updateVulnerability); +627 DBUtils.closeStatement(deleteVulnerability); +628 DBUtils.closeStatement(insertVulnerability); +629 DBUtils.closeStatement(insertReference); +630 DBUtils.closeStatement(selectCpeId); +631 DBUtils.closeStatement(insertCpe); +632 DBUtils.closeStatement(insertSoftware); +633 } +634 } +635 +636 /** +637 * Checks to see if data exists so that analysis can be performed. +638 * +639 * @return <code>true</code> if data exists; otherwise <code>false</code> +640 */ +641 public boolean dataExists() { +642 Statement cs = null; +643 ResultSet rs = null; +644 try { +645 cs = conn.createStatement(); +646 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); +647 if (rs.next()) { +648 if (rs.getInt(1) > 0) { +649 return true; +650 } +651 } +652 } catch (SQLException ex) { +653 String dd; +654 try { +655 dd = Settings.getDataDirectory().getAbsolutePath(); +656 } catch (IOException ex1) { +657 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +658 } +659 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. " +660 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please " +661 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " +662 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n", +663 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); +664 LOGGER.debug("", ex); +665 } finally { +666 DBUtils.closeResultSet(rs); +667 DBUtils.closeStatement(cs); +668 } +669 return false; +670 } +671 +672 /** +673 * It is possible that orphaned rows may be generated during database +674 * updates. This should be called after all updates have been completed to +675 * ensure orphan entries are removed. +676 */ +677 public void cleanupDatabase() { +678 PreparedStatement ps = null; +679 try { +680 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); +681 if (ps != null) { +682 ps.executeUpdate(); +683 } +684 } catch (SQLException ex) { +685 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +686 LOGGER.debug("", ex); +687 } finally { +688 DBUtils.closeStatement(ps); +689 } +690 } +691 +692 /** +693 * Determines if the given identifiedVersion is affected by the given cpeId +694 * and previous version flag. A non-null, non-empty string passed to the +695 * previous version argument indicates that all previous versions are +696 * affected. +697 * +698 * @param vendor the vendor of the dependency being analyzed +699 * @param product the product name of the dependency being analyzed +700 * @param vulnerableSoftware a map of the vulnerable software with a boolean +701 * indicating if all previous versions are affected +702 * @param identifiedVersion the identified version of the dependency being +703 * analyzed +704 * @return true if the identified version is affected, otherwise false +705 */ +706 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, +707 DependencyVersion identifiedVersion) { +708 +709 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); +710 +711 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); +712 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); +713 String majorVersionMatch = null; +714 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +715 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +716 if (v == null || "-".equals(v.toString())) { //all versions +717 return entry; +718 } +719 if (entry.getValue()) { +720 if (matchesAnyPrevious) { +721 return entry; +722 } +723 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { +724 majorVersionMatch = v.getVersionParts().get(0); +725 } +726 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); +727 } +728 } +729 if (matchesAnyPrevious) { +730 return null; +731 } +732 +733 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; +734 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions +735 //then later we process those that affect all versions. This could be done with sorting... +736 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +737 if (!entry.getValue()) { +738 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +739 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +740 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +741 continue; +742 } +743 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +744 //in the above loop or just after loop (if matchesAnyPrevious return null). +745 if (identifiedVersion.equals(v)) { +746 return entry; +747 } 748 } -749 cpeVersion = DependencyVersionUtil.parseVersion(versionText); -750 } else { -751 cpeVersion = new DependencyVersion("-"); -752 } -753 return cpeVersion; -754 } -755 -756 /** -757 * This method is only referenced in unused code. -758 * -759 * Deletes unused dictionary entries from the database. -760 */ -761 public void deleteUnusedCpe() { -762 CallableStatement cs = null; -763 try { -764 cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); -765 cs.executeUpdate(); -766 } catch (SQLException ex) { -767 LOGGER.error("Unable to delete CPE dictionary entries", ex); -768 } finally { -769 DBUtils.closeStatement(cs); -770 } -771 } -772 -773 /** -774 * This method is only referenced in unused code and will likely break on MySQL if ever used due to the MERGE statement. -775 * -776 * Merges CPE entries into the database. -777 * -778 * @param cpe the CPE identifier -779 * @param vendor the CPE vendor -780 * @param product the CPE product -781 */ -782 public void addCpe(String cpe, String vendor, String product) { -783 PreparedStatement ps = null; -784 try { -785 ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE")); -786 ps.setString(1, cpe); -787 ps.setString(2, vendor); -788 ps.setString(3, product); -789 ps.executeUpdate(); -790 } catch (SQLException ex) { -791 LOGGER.error("Unable to add CPE dictionary entry", ex); -792 } finally { -793 DBUtils.closeStatement(ps); -794 } -795 } -796 } +749 } +750 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +751 if (entry.getValue()) { +752 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +753 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +754 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +755 continue; +756 } +757 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +758 //in the above loop or just after loop (if matchesAnyPrevious return null). +759 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { +760 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { +761 return entry; +762 } +763 } +764 } +765 } +766 return null; +767 } +768 +769 /** +770 * Parses the version (including revision) from a CPE identifier. If no +771 * version is identified then a '-' is returned. +772 * +773 * @param cpeStr a cpe identifier +774 * @return a dependency version +775 */ +776 private DependencyVersion parseDependencyVersion(String cpeStr) { +777 final VulnerableSoftware cpe = new VulnerableSoftware(); +778 try { +779 cpe.parseName(cpeStr); +780 } catch (UnsupportedEncodingException ex) { +781 //never going to happen. +782 LOGGER.trace("", ex); +783 } +784 return parseDependencyVersion(cpe); +785 } +786 +787 /** +788 * Takes a CPE and parses out the version number. If no version is +789 * identified then a '-' is returned. +790 * +791 * @param cpe a cpe object +792 * @return a dependency version +793 */ +794 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { +795 final DependencyVersion cpeVersion; +796 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { +797 final String versionText; +798 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) { +799 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate()); +800 } else { +801 versionText = cpe.getVersion(); +802 } +803 cpeVersion = DependencyVersionUtil.parseVersion(versionText); +804 } else { +805 cpeVersion = new DependencyVersion("-"); +806 } +807 return cpeVersion; +808 } +809 +810 /** +811 * This method is only referenced in unused code. +812 * +813 * Deletes unused dictionary entries from the database. +814 */ +815 public void deleteUnusedCpe() { +816 CallableStatement cs = null; +817 try { +818 cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); +819 cs.executeUpdate(); +820 } catch (SQLException ex) { +821 LOGGER.error("Unable to delete CPE dictionary entries", ex); +822 } finally { +823 DBUtils.closeStatement(cs); +824 } +825 } +826 +827 /** +828 * This method is only referenced in unused code and will likely break on +829 * MySQL if ever used due to the MERGE statement. +830 * +831 * Merges CPE entries into the database. +832 * +833 * @param cpe the CPE identifier +834 * @param vendor the CPE vendor +835 * @param product the CPE product +836 */ +837 public void addCpe(String cpe, String vendor, String product) { +838 PreparedStatement ps = null; +839 try { +840 ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE")); +841 ps.setString(1, cpe); +842 ps.setString(2, vendor); +843 ps.setString(3, product); +844 ps.executeUpdate(); +845 } catch (SQLException ex) { +846 LOGGER.error("Unable to add CPE dictionary entry", ex); +847 } finally { +848 DBUtils.closeStatement(ps); +849 } +850 } +851 }
      diff --git a/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html b/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html index 724ed3187..d89cd7707 100644 --- a/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html index 691167729..88465d252 100644 --- a/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html b/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html index 1f8984c51..2e9ae7430 100644 --- a/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html +++ b/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html @@ -68,287 +68,300 @@ 60 61 /** 62 * <p> -63 * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.</p> -64 * -65 * @throws UpdateException is thrown if there is an error updating the database -66 */ -67 @Override -68 public void update() throws UpdateException { -69 try { -70 openDataStores(); -71 boolean autoUpdate = true; -72 try { -73 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -74 } catch (InvalidSettingException ex) { -75 LOGGER.debug("Invalid setting for auto-update; using true."); -76 } -77 if (autoUpdate && checkUpdate()) { -78 final UpdateableNvdCve updateable = getUpdatesNeeded(); -79 if (updateable.isUpdateNeeded()) { -80 performUpdate(updateable); -81 } -82 } -83 } catch (MalformedURLException ex) { -84 LOGGER.warn( -85 "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data."); -86 LOGGER.debug("", ex); -87 } catch (DownloadFailedException ex) { -88 LOGGER.warn( -89 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); -90 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { -91 LOGGER.info( -92 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); -93 } -94 LOGGER.debug("", ex); -95 } finally { -96 closeDataStores(); -97 } -98 } -99 -100 /** -101 * Checks if the NVD CVE XML files were last checked recently. As an optimization, we can avoid repetitive checks against the -102 * NVD. Setting CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before checking again. A database property -103 * stores the timestamp of the last check. -104 * -105 * @return true to proceed with the check, or false to skip. -106 * @throws UpdateException thrown when there is an issue checking for updates. -107 */ -108 private boolean checkUpdate() throws UpdateException { -109 boolean proceed = true; -110 // If the valid setting has not been specified, then we proceed to check... -111 final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0); -112 if (dataExists() && 0 < validForHours) { -113 // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec -114 final long msValid = validForHours * 60L * 60L * 1000L; -115 final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0")); -116 final long now = System.currentTimeMillis(); -117 proceed = (now - lastChecked) > msValid; -118 if (proceed) { -119 getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(now)); -120 } else { -121 LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours); -122 LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.", -123 lastChecked, now, msValid); -124 } -125 } -126 return proceed; -127 } -128 -129 /** -130 * Checks the CVE Index to ensure data exists and analysis can continue. -131 * -132 * @return true if the database contains data -133 */ -134 private boolean dataExists() { -135 CveDB cve = null; -136 try { -137 cve = new CveDB(); -138 cve.open(); -139 return cve.dataExists(); -140 } catch (DatabaseException ex) { -141 return false; -142 } finally { -143 if (cve != null) { -144 cve.close(); -145 } -146 } -147 } -148 -149 /** -150 * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database. -151 * -152 * @param updateable a collection of NVD CVE data file references that need to be downloaded and processed to update the -153 * database -154 * @throws UpdateException is thrown if there is an error updating the database -155 */ -156 public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { -157 int maxUpdates = 0; -158 try { -159 for (NvdCveInfo cve : updateable) { -160 if (cve.getNeedsUpdate()) { -161 maxUpdates += 1; -162 } -163 } -164 if (maxUpdates <= 0) { -165 return; -166 } -167 if (maxUpdates > 3) { -168 LOGGER.info( -169 "NVD CVE requires several updates; this could take a couple of minutes."); -170 } -171 if (maxUpdates > 0) { -172 openDataStores(); -173 } -174 -175 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; -176 -177 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); -178 final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); -179 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates); -180 for (NvdCveInfo cve : updateable) { -181 if (cve.getNeedsUpdate()) { -182 final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance()); -183 downloadFutures.add(downloadExecutors.submit(call)); -184 } -185 } -186 downloadExecutors.shutdown(); -187 -188 //next, move the future future processTasks to just future processTasks -189 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates); -190 for (Future<Future<ProcessTask>> future : downloadFutures) { -191 Future<ProcessTask> task = null; -192 try { -193 task = future.get(); -194 } catch (InterruptedException ex) { -195 downloadExecutors.shutdownNow(); -196 processExecutor.shutdownNow(); -197 -198 LOGGER.debug("Thread was interrupted during download", ex); -199 throw new UpdateException("The download was interrupted", ex); -200 } catch (ExecutionException ex) { +63 * Downloads the latest NVD CVE XML file from the web and imports it into +64 * the current CVE Database.</p> +65 * +66 * @throws UpdateException is thrown if there is an error updating the +67 * database +68 */ +69 @Override +70 public void update() throws UpdateException { +71 try { +72 openDataStores(); +73 boolean autoUpdate = true; +74 try { +75 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +76 } catch (InvalidSettingException ex) { +77 LOGGER.debug("Invalid setting for auto-update; using true."); +78 } +79 if (autoUpdate && checkUpdate()) { +80 final UpdateableNvdCve updateable = getUpdatesNeeded(); +81 getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); +82 if (updateable.isUpdateNeeded()) { +83 performUpdate(updateable); +84 } +85 } +86 } catch (MalformedURLException ex) { +87 LOGGER.warn( +88 "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data."); +89 LOGGER.debug("", ex); +90 } catch (DownloadFailedException ex) { +91 LOGGER.warn( +92 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); +93 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { +94 LOGGER.info( +95 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); +96 } +97 LOGGER.debug("", ex); +98 } finally { +99 closeDataStores(); +100 } +101 } +102 +103 /** +104 * Checks if the NVD CVE XML files were last checked recently. As an +105 * optimization, we can avoid repetitive checks against the NVD. Setting +106 * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before +107 * checking again. A database property stores the timestamp of the last +108 * check. +109 * +110 * @return true to proceed with the check, or false to skip. +111 * @throws UpdateException thrown when there is an issue checking for +112 * updates. +113 */ +114 private boolean checkUpdate() throws UpdateException { +115 boolean proceed = true; +116 // If the valid setting has not been specified, then we proceed to check... +117 final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0); +118 if (dataExists() && 0 < validForHours) { +119 // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec +120 final long msValid = validForHours * 60L * 60L * 1000L; +121 final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0")); +122 final long now = System.currentTimeMillis(); +123 proceed = (now - lastChecked) > msValid; +124 if (!proceed) { +125 LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours); +126 LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.", +127 lastChecked, now, msValid); +128 } +129 } +130 return proceed; +131 } +132 +133 /** +134 * Checks the CVE Index to ensure data exists and analysis can continue. +135 * +136 * @return true if the database contains data +137 */ +138 private boolean dataExists() { +139 CveDB cve = null; +140 try { +141 cve = new CveDB(); +142 cve.open(); +143 return cve.dataExists(); +144 } catch (DatabaseException ex) { +145 return false; +146 } finally { +147 if (cve != null) { +148 cve.close(); +149 } +150 } +151 } +152 +153 /** +154 * Downloads the latest NVD CVE XML file from the web and imports it into +155 * the current CVE Database. +156 * +157 * @param updateable a collection of NVD CVE data file references that need +158 * to be downloaded and processed to update the database +159 * @throws UpdateException is thrown if there is an error updating the +160 * database +161 */ +162 public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { +163 int maxUpdates = 0; +164 try { +165 for (NvdCveInfo cve : updateable) { +166 if (cve.getNeedsUpdate()) { +167 maxUpdates += 1; +168 } +169 } +170 if (maxUpdates <= 0) { +171 return; +172 } +173 if (maxUpdates > 3) { +174 LOGGER.info( +175 "NVD CVE requires several updates; this could take a couple of minutes."); +176 } +177 if (maxUpdates > 0) { +178 openDataStores(); +179 } +180 +181 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; +182 +183 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); +184 final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); +185 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates); +186 for (NvdCveInfo cve : updateable) { +187 if (cve.getNeedsUpdate()) { +188 final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance()); +189 downloadFutures.add(downloadExecutors.submit(call)); +190 } +191 } +192 downloadExecutors.shutdown(); +193 +194 //next, move the future future processTasks to just future processTasks +195 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates); +196 for (Future<Future<ProcessTask>> future : downloadFutures) { +197 Future<ProcessTask> task = null; +198 try { +199 task = future.get(); +200 } catch (InterruptedException ex) { 201 downloadExecutors.shutdownNow(); 202 processExecutor.shutdownNow(); 203 -204 LOGGER.debug("Thread was interrupted during download execution", ex); -205 throw new UpdateException("The execution of the download was interrupted", ex); -206 } -207 if (task == null) { -208 downloadExecutors.shutdownNow(); -209 processExecutor.shutdownNow(); -210 LOGGER.debug("Thread was interrupted during download"); -211 throw new UpdateException("The download was interrupted; unable to complete the update"); -212 } else { -213 processFutures.add(task); -214 } -215 } -216 -217 for (Future<ProcessTask> future : processFutures) { -218 try { -219 final ProcessTask task = future.get(); -220 if (task.getException() != null) { -221 throw task.getException(); -222 } -223 } catch (InterruptedException ex) { -224 processExecutor.shutdownNow(); -225 LOGGER.debug("Thread was interrupted during processing", ex); -226 throw new UpdateException(ex); -227 } catch (ExecutionException ex) { -228 processExecutor.shutdownNow(); -229 LOGGER.debug("Execution Exception during process", ex); -230 throw new UpdateException(ex); -231 } finally { -232 processExecutor.shutdown(); -233 } -234 } -235 -236 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it) -237 getProperties().save(updateable.get(MODIFIED)); -238 LOGGER.info("Begin database maintenance."); -239 getCveDB().cleanupDatabase(); -240 LOGGER.info("End database maintenance."); -241 } -242 } finally { -243 closeDataStores(); -244 } -245 } -246 -247 /** -248 * Determines if the index needs to be updated. This is done by fetching the NVD CVE meta data and checking the last update -249 * date. If the data needs to be refreshed this method will return the NvdCveUrl for the files that need to be updated. -250 * -251 * @return the collection of files that need to be updated -252 * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta data is incorrect -253 * @throws DownloadFailedException is thrown if there is an error. downloading the NVD CVE download data file -254 * @throws UpdateException Is thrown if there is an issue with the last updated properties file -255 */ -256 protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { -257 UpdateableNvdCve updates = null; -258 try { -259 updates = retrieveCurrentTimestampsFromWeb(); -260 } catch (InvalidDataException ex) { -261 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page"; -262 LOGGER.debug(msg, ex); -263 throw new DownloadFailedException(msg, ex); -264 } catch (InvalidSettingException ex) { -265 LOGGER.debug("Invalid setting found when retrieving timestamps", ex); -266 throw new DownloadFailedException("Invalid settings", ex); -267 } -268 -269 if (updates == null) { -270 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data"); -271 } -272 if (!getProperties().isEmpty()) { -273 try { -274 final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0")); -275 final long now = System.currentTimeMillis(); -276 final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7); -277 if (lastUpdated == updates.getTimeStamp(MODIFIED)) { -278 updates.clear(); //we don't need to update anything. -279 } else if (DateUtil.withinDateRange(lastUpdated, now, days)) { -280 for (NvdCveInfo entry : updates) { -281 if (MODIFIED.equals(entry.getId())) { -282 entry.setNeedsUpdate(true); -283 } else { -284 entry.setNeedsUpdate(false); -285 } -286 } -287 } else { //we figure out which of the several XML files need to be downloaded. -288 for (NvdCveInfo entry : updates) { -289 if (MODIFIED.equals(entry.getId())) { -290 entry.setNeedsUpdate(true); -291 } else { -292 long currentTimestamp = 0; -293 try { -294 currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE -295 + entry.getId(), "0")); -296 } catch (NumberFormatException ex) { -297 LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated", -298 DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex); -299 } -300 if (currentTimestamp == entry.getTimestamp()) { -301 entry.setNeedsUpdate(false); -302 } -303 } -304 } -305 } -306 } catch (NumberFormatException ex) { -307 LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); -308 LOGGER.debug("", ex); -309 } -310 } -311 return updates; -312 } -313 -314 /** -315 * Retrieves the timestamps from the NVD CVE meta data file. -316 * -317 * @return the timestamp from the currently published nvdcve downloads page -318 * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data is incorrect. -319 * @throws DownloadFailedException thrown if there is an error downloading the nvd cve meta data file -320 * @throws InvalidDataException thrown if there is an exception parsing the timestamps -321 * @throws InvalidSettingException thrown if the settings are invalid -322 */ -323 private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() -324 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException { -325 -326 final UpdateableNvdCve updates = new UpdateableNvdCve(); -327 updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL), -328 Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL), -329 false); -330 -331 final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR); -332 final int end = Calendar.getInstance().get(Calendar.YEAR); -333 final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0); -334 final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2); -335 for (int i = start; i <= end; i++) { -336 updates.add(Integer.toString(i), String.format(baseUrl20, i), -337 String.format(baseUrl12, i), -338 true); -339 } -340 return updates; -341 } -342 -343 } +204 LOGGER.debug("Thread was interrupted during download", ex); +205 throw new UpdateException("The download was interrupted", ex); +206 } catch (ExecutionException ex) { +207 downloadExecutors.shutdownNow(); +208 processExecutor.shutdownNow(); +209 +210 LOGGER.debug("Thread was interrupted during download execution", ex); +211 throw new UpdateException("The execution of the download was interrupted", ex); +212 } +213 if (task == null) { +214 downloadExecutors.shutdownNow(); +215 processExecutor.shutdownNow(); +216 LOGGER.debug("Thread was interrupted during download"); +217 throw new UpdateException("The download was interrupted; unable to complete the update"); +218 } else { +219 processFutures.add(task); +220 } +221 } +222 +223 for (Future<ProcessTask> future : processFutures) { +224 try { +225 final ProcessTask task = future.get(); +226 if (task.getException() != null) { +227 throw task.getException(); +228 } +229 } catch (InterruptedException ex) { +230 processExecutor.shutdownNow(); +231 LOGGER.debug("Thread was interrupted during processing", ex); +232 throw new UpdateException(ex); +233 } catch (ExecutionException ex) { +234 processExecutor.shutdownNow(); +235 LOGGER.debug("Execution Exception during process", ex); +236 throw new UpdateException(ex); +237 } finally { +238 processExecutor.shutdown(); +239 } +240 } +241 +242 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it) +243 getProperties().save(updateable.get(MODIFIED)); +244 LOGGER.info("Begin database maintenance."); +245 getCveDB().cleanupDatabase(); +246 LOGGER.info("End database maintenance."); +247 } +248 } finally { +249 closeDataStores(); +250 } +251 } +252 +253 /** +254 * Determines if the index needs to be updated. This is done by fetching the +255 * NVD CVE meta data and checking the last update date. If the data needs to +256 * be refreshed this method will return the NvdCveUrl for the files that +257 * need to be updated. +258 * +259 * @return the collection of files that need to be updated +260 * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta +261 * data is incorrect +262 * @throws DownloadFailedException is thrown if there is an error. +263 * downloading the NVD CVE download data file +264 * @throws UpdateException Is thrown if there is an issue with the last +265 * updated properties file +266 */ +267 protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { +268 UpdateableNvdCve updates = null; +269 try { +270 updates = retrieveCurrentTimestampsFromWeb(); +271 } catch (InvalidDataException ex) { +272 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page"; +273 LOGGER.debug(msg, ex); +274 throw new DownloadFailedException(msg, ex); +275 } catch (InvalidSettingException ex) { +276 LOGGER.debug("Invalid setting found when retrieving timestamps", ex); +277 throw new DownloadFailedException("Invalid settings", ex); +278 } +279 +280 if (updates == null) { +281 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data"); +282 } +283 if (!getProperties().isEmpty()) { +284 try { +285 final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0")); +286 final long now = System.currentTimeMillis(); +287 final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7); +288 if (lastUpdated == updates.getTimeStamp(MODIFIED)) { +289 updates.clear(); //we don't need to update anything. +290 } else if (DateUtil.withinDateRange(lastUpdated, now, days)) { +291 for (NvdCveInfo entry : updates) { +292 if (MODIFIED.equals(entry.getId())) { +293 entry.setNeedsUpdate(true); +294 } else { +295 entry.setNeedsUpdate(false); +296 } +297 } +298 } else { //we figure out which of the several XML files need to be downloaded. +299 for (NvdCveInfo entry : updates) { +300 if (MODIFIED.equals(entry.getId())) { +301 entry.setNeedsUpdate(true); +302 } else { +303 long currentTimestamp = 0; +304 try { +305 currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE +306 + entry.getId(), "0")); +307 } catch (NumberFormatException ex) { +308 LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated", +309 DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex); +310 } +311 if (currentTimestamp == entry.getTimestamp()) { +312 entry.setNeedsUpdate(false); +313 } +314 } +315 } +316 } +317 } catch (NumberFormatException ex) { +318 LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); +319 LOGGER.debug("", ex); +320 } +321 } +322 return updates; +323 } +324 +325 /** +326 * Retrieves the timestamps from the NVD CVE meta data file. +327 * +328 * @return the timestamp from the currently published nvdcve downloads page +329 * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data +330 * is incorrect. +331 * @throws DownloadFailedException thrown if there is an error downloading +332 * the nvd cve meta data file +333 * @throws InvalidDataException thrown if there is an exception parsing the +334 * timestamps +335 * @throws InvalidSettingException thrown if the settings are invalid +336 */ +337 private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() +338 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException { +339 +340 final UpdateableNvdCve updates = new UpdateableNvdCve(); +341 updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL), +342 Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL), +343 false); +344 +345 final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR); +346 final int end = Calendar.getInstance().get(Calendar.YEAR); +347 final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0); +348 final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2); +349 for (int i = start; i <= end; i++) { +350 updates.add(Integer.toString(i), String.format(baseUrl20, i), +351 String.format(baseUrl12, i), +352 true); +353 } +354 return updates; +355 } +356 }
      diff --git a/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html b/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html index f1598414b..e50f3bb2f 100644 --- a/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update.cpe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.cpe diff --git a/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html b/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html index c789246fd..d93c53a57 100644 --- a/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update.cpe + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.cpe diff --git a/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html b/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html index 637de6283..b5b9b60ca 100644 --- a/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.exception diff --git a/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html b/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html index dcf7ccad3..199e952ce 100644 --- a/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.exception diff --git a/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html b/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html index 42de7439d..dd7845863 100644 --- a/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html +++ b/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html @@ -269,62 +269,63 @@ 261 try { 262 is.close(); 263 } catch (IOException ex) { -264 } -265 } -266 } -267 } -268 -269 /** -270 * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified. -271 * -272 * @param file the archive file -273 * @throws FileNotFoundException thrown if the file does not exist -274 * @throws IOException thrown if there is an error extracting the file. -275 */ -276 private void extractGzip(File file) throws FileNotFoundException, IOException { -277 final String originalPath = file.getPath(); -278 final File gzip = new File(originalPath + ".gz"); -279 if (gzip.isFile() && !gzip.delete()) { -280 gzip.deleteOnExit(); -281 } -282 if (!file.renameTo(gzip)) { -283 throw new IOException("Unable to rename '" + file.getPath() + "'"); -284 } -285 final File newfile = new File(originalPath); -286 -287 final byte[] buffer = new byte[4096]; -288 -289 GZIPInputStream cin = null; -290 FileOutputStream out = null; -291 try { -292 cin = new GZIPInputStream(new FileInputStream(gzip)); -293 out = new FileOutputStream(newfile); -294 -295 int len; -296 while ((len = cin.read(buffer)) > 0) { -297 out.write(buffer, 0, len); -298 } -299 } finally { -300 if (cin != null) { -301 try { -302 cin.close(); -303 } catch (IOException ex) { -304 LOGGER.trace("ignore", ex); -305 } -306 } -307 if (out != null) { -308 try { -309 out.close(); -310 } catch (IOException ex) { -311 LOGGER.trace("ignore", ex); -312 } -313 } -314 if (gzip.isFile()) { -315 FileUtils.deleteQuietly(gzip); -316 } -317 } -318 } -319 } +264 LOGGER.debug("Error closing stream", ex); +265 } +266 } +267 } +268 } +269 +270 /** +271 * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified. +272 * +273 * @param file the archive file +274 * @throws FileNotFoundException thrown if the file does not exist +275 * @throws IOException thrown if there is an error extracting the file. +276 */ +277 private void extractGzip(File file) throws FileNotFoundException, IOException { +278 final String originalPath = file.getPath(); +279 final File gzip = new File(originalPath + ".gz"); +280 if (gzip.isFile() && !gzip.delete()) { +281 gzip.deleteOnExit(); +282 } +283 if (!file.renameTo(gzip)) { +284 throw new IOException("Unable to rename '" + file.getPath() + "'"); +285 } +286 final File newfile = new File(originalPath); +287 +288 final byte[] buffer = new byte[4096]; +289 +290 GZIPInputStream cin = null; +291 FileOutputStream out = null; +292 try { +293 cin = new GZIPInputStream(new FileInputStream(gzip)); +294 out = new FileOutputStream(newfile); +295 +296 int len; +297 while ((len = cin.read(buffer)) > 0) { +298 out.write(buffer, 0, len); +299 } +300 } finally { +301 if (cin != null) { +302 try { +303 cin.close(); +304 } catch (IOException ex) { +305 LOGGER.trace("ignore", ex); +306 } +307 } +308 if (out != null) { +309 try { +310 out.close(); +311 } catch (IOException ex) { +312 LOGGER.trace("ignore", ex); +313 } +314 } +315 if (gzip.isFile()) { +316 FileUtils.deleteQuietly(gzip); +317 } +318 } +319 } +320 }
      diff --git a/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html b/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html index f84de6677..6cd7a2b99 100644 --- a/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html +++ b/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html @@ -262,245 +262,244 @@ 254 * @throws IOException thrown if there is an IOException with the CPE Index 255 */ 256 private void saveEntry(Vulnerability vuln) throws DatabaseException, CorruptIndexException, IOException { -257 if (cveDB == null) { -258 return; -259 } -260 final String cveName = vuln.getName(); -261 if (prevVersionVulnMap.containsKey(cveName)) { -262 final List<VulnerableSoftware> vulnSoftware = prevVersionVulnMap.get(cveName); -263 for (VulnerableSoftware vs : vulnSoftware) { -264 vuln.updateVulnerableSoftware(vs); -265 } +257 final String cveName = vuln.getName(); +258 if (prevVersionVulnMap != null && prevVersionVulnMap.containsKey(cveName)) { +259 final List<VulnerableSoftware> vulnSoftware = prevVersionVulnMap.get(cveName); +260 for (VulnerableSoftware vs : vulnSoftware) { +261 vuln.updateVulnerableSoftware(vs); +262 } +263 } +264 if (cveDB != null) { +265 cveDB.updateVulnerability(vuln); 266 } -267 cveDB.updateVulnerability(vuln); -268 } -269 -270 // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node"> -271 /** -272 * A simple class to maintain information about the current element while parsing the NVD CVE XML. -273 */ -274 protected static class Element { -275 -276 /** -277 * A node type in the NVD CVE Schema 2.0 -278 */ -279 public static final String NVD = "nvd"; -280 /** -281 * A node type in the NVD CVE Schema 2.0 -282 */ -283 public static final String ENTRY = "entry"; -284 /** -285 * A node type in the NVD CVE Schema 2.0 -286 */ -287 public static final String VULN_PRODUCT = "vuln:product"; -288 /** -289 * A node type in the NVD CVE Schema 2.0 -290 */ -291 public static final String VULN_REFERENCES = "vuln:references"; -292 /** -293 * A node type in the NVD CVE Schema 2.0 -294 */ -295 public static final String VULN_SOURCE = "vuln:source"; -296 /** -297 * A node type in the NVD CVE Schema 2.0 -298 */ -299 public static final String VULN_REFERENCE = "vuln:reference"; -300 /** -301 * A node type in the NVD CVE Schema 2.0 -302 */ -303 public static final String VULN_SUMMARY = "vuln:summary"; -304 /** -305 * A node type in the NVD CVE Schema 2.0 -306 */ -307 public static final String VULN_CWE = "vuln:cwe"; -308 /** -309 * A node type in the NVD CVE Schema 2.0 -310 */ -311 public static final String CVSS_SCORE = "cvss:score"; -312 /** -313 * A node type in the NVD CVE Schema 2.0 -314 */ -315 public static final String CVSS_ACCESS_VECTOR = "cvss:access-vector"; -316 /** -317 * A node type in the NVD CVE Schema 2.0 -318 */ -319 public static final String CVSS_ACCESS_COMPLEXITY = "cvss:access-complexity"; -320 /** -321 * A node type in the NVD CVE Schema 2.0 -322 */ -323 public static final String CVSS_AUTHENTICATION = "cvss:authentication"; -324 /** -325 * A node type in the NVD CVE Schema 2.0 -326 */ -327 public static final String CVSS_CONFIDENTIALITY_IMPACT = "cvss:confidentiality-impact"; -328 /** -329 * A node type in the NVD CVE Schema 2.0 -330 */ -331 public static final String CVSS_INTEGRITY_IMPACT = "cvss:integrity-impact"; -332 /** -333 * A node type in the NVD CVE Schema 2.0 -334 */ -335 public static final String CVSS_AVAILABILITY_IMPACT = "cvss:availability-impact"; -336 /** -337 * The current node. -338 */ -339 private String node; -340 -341 /** -342 * Gets the value of node. -343 * -344 * @return the value of node -345 */ -346 public String getNode() { -347 return this.node; -348 } -349 -350 /** -351 * Sets the value of node. -352 * -353 * @param node new value of node -354 */ -355 public void setNode(String node) { -356 this.node = node; -357 } -358 -359 /** -360 * Checks if the handler is at the NVD node. -361 * -362 * @return true or false -363 */ -364 public boolean isNVDNode() { -365 return NVD.equals(node); -366 } -367 -368 /** -369 * Checks if the handler is at the ENTRY node. -370 * -371 * @return true or false -372 */ -373 public boolean isEntryNode() { -374 return ENTRY.equals(node); -375 } -376 -377 /** -378 * Checks if the handler is at the VULN_PRODUCT node. -379 * -380 * @return true or false -381 */ -382 public boolean isVulnProductNode() { -383 return VULN_PRODUCT.equals(node); -384 } -385 -386 /** -387 * Checks if the handler is at the REFERENCES node. -388 * -389 * @return true or false -390 */ -391 public boolean isVulnReferencesNode() { -392 return VULN_REFERENCES.equals(node); -393 } -394 -395 /** -396 * Checks if the handler is at the REFERENCE node. -397 * -398 * @return true or false -399 */ -400 public boolean isVulnReferenceNode() { -401 return VULN_REFERENCE.equals(node); -402 } -403 -404 /** -405 * Checks if the handler is at the VULN_SOURCE node. -406 * -407 * @return true or false -408 */ -409 public boolean isVulnSourceNode() { -410 return VULN_SOURCE.equals(node); -411 } -412 -413 /** -414 * Checks if the handler is at the VULN_SUMMARY node. -415 * -416 * @return true or false -417 */ -418 public boolean isVulnSummaryNode() { -419 return VULN_SUMMARY.equals(node); -420 } -421 -422 /** -423 * Checks if the handler is at the VULN_CWE node. -424 * -425 * @return true or false -426 */ -427 public boolean isVulnCWENode() { -428 return VULN_CWE.equals(node); -429 } -430 -431 /** -432 * Checks if the handler is at the CVSS_SCORE node. -433 * -434 * @return true or false -435 */ -436 public boolean isCVSSScoreNode() { -437 return CVSS_SCORE.equals(node); -438 } -439 -440 /** -441 * Checks if the handler is at the CVSS_ACCESS_VECTOR node. -442 * -443 * @return true or false -444 */ -445 public boolean isCVSSAccessVectorNode() { -446 return CVSS_ACCESS_VECTOR.equals(node); -447 } -448 -449 /** -450 * Checks if the handler is at the CVSS_ACCESS_COMPLEXITY node. -451 * -452 * @return true or false -453 */ -454 public boolean isCVSSAccessComplexityNode() { -455 return CVSS_ACCESS_COMPLEXITY.equals(node); -456 } -457 -458 /** -459 * Checks if the handler is at the CVSS_AUTHENTICATION node. -460 * -461 * @return true or false -462 */ -463 public boolean isCVSSAuthenticationNode() { -464 return CVSS_AUTHENTICATION.equals(node); -465 } -466 -467 /** -468 * Checks if the handler is at the CVSS_CONFIDENTIALITY_IMPACT node. -469 * -470 * @return true or false -471 */ -472 public boolean isCVSSConfidentialityImpactNode() { -473 return CVSS_CONFIDENTIALITY_IMPACT.equals(node); -474 } -475 -476 /** -477 * Checks if the handler is at the CVSS_INTEGRITY_IMPACT node. -478 * -479 * @return true or false -480 */ -481 public boolean isCVSSIntegrityImpactNode() { -482 return CVSS_INTEGRITY_IMPACT.equals(node); -483 } -484 -485 /** -486 * Checks if the handler is at the CVSS_AVAILABILITY_IMPACT node. -487 * -488 * @return true or false -489 */ -490 public boolean isCVSSAvailabilityImpactNode() { -491 return CVSS_AVAILABILITY_IMPACT.equals(node); -492 } -493 } -494 // </editor-fold> -495 } +267 } +268 +269 // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node"> +270 /** +271 * A simple class to maintain information about the current element while parsing the NVD CVE XML. +272 */ +273 protected static class Element { +274 +275 /** +276 * A node type in the NVD CVE Schema 2.0 +277 */ +278 public static final String NVD = "nvd"; +279 /** +280 * A node type in the NVD CVE Schema 2.0 +281 */ +282 public static final String ENTRY = "entry"; +283 /** +284 * A node type in the NVD CVE Schema 2.0 +285 */ +286 public static final String VULN_PRODUCT = "vuln:product"; +287 /** +288 * A node type in the NVD CVE Schema 2.0 +289 */ +290 public static final String VULN_REFERENCES = "vuln:references"; +291 /** +292 * A node type in the NVD CVE Schema 2.0 +293 */ +294 public static final String VULN_SOURCE = "vuln:source"; +295 /** +296 * A node type in the NVD CVE Schema 2.0 +297 */ +298 public static final String VULN_REFERENCE = "vuln:reference"; +299 /** +300 * A node type in the NVD CVE Schema 2.0 +301 */ +302 public static final String VULN_SUMMARY = "vuln:summary"; +303 /** +304 * A node type in the NVD CVE Schema 2.0 +305 */ +306 public static final String VULN_CWE = "vuln:cwe"; +307 /** +308 * A node type in the NVD CVE Schema 2.0 +309 */ +310 public static final String CVSS_SCORE = "cvss:score"; +311 /** +312 * A node type in the NVD CVE Schema 2.0 +313 */ +314 public static final String CVSS_ACCESS_VECTOR = "cvss:access-vector"; +315 /** +316 * A node type in the NVD CVE Schema 2.0 +317 */ +318 public static final String CVSS_ACCESS_COMPLEXITY = "cvss:access-complexity"; +319 /** +320 * A node type in the NVD CVE Schema 2.0 +321 */ +322 public static final String CVSS_AUTHENTICATION = "cvss:authentication"; +323 /** +324 * A node type in the NVD CVE Schema 2.0 +325 */ +326 public static final String CVSS_CONFIDENTIALITY_IMPACT = "cvss:confidentiality-impact"; +327 /** +328 * A node type in the NVD CVE Schema 2.0 +329 */ +330 public static final String CVSS_INTEGRITY_IMPACT = "cvss:integrity-impact"; +331 /** +332 * A node type in the NVD CVE Schema 2.0 +333 */ +334 public static final String CVSS_AVAILABILITY_IMPACT = "cvss:availability-impact"; +335 /** +336 * The current node. +337 */ +338 private String node; +339 +340 /** +341 * Gets the value of node. +342 * +343 * @return the value of node +344 */ +345 public String getNode() { +346 return this.node; +347 } +348 +349 /** +350 * Sets the value of node. +351 * +352 * @param node new value of node +353 */ +354 public void setNode(String node) { +355 this.node = node; +356 } +357 +358 /** +359 * Checks if the handler is at the NVD node. +360 * +361 * @return true or false +362 */ +363 public boolean isNVDNode() { +364 return NVD.equals(node); +365 } +366 +367 /** +368 * Checks if the handler is at the ENTRY node. +369 * +370 * @return true or false +371 */ +372 public boolean isEntryNode() { +373 return ENTRY.equals(node); +374 } +375 +376 /** +377 * Checks if the handler is at the VULN_PRODUCT node. +378 * +379 * @return true or false +380 */ +381 public boolean isVulnProductNode() { +382 return VULN_PRODUCT.equals(node); +383 } +384 +385 /** +386 * Checks if the handler is at the REFERENCES node. +387 * +388 * @return true or false +389 */ +390 public boolean isVulnReferencesNode() { +391 return VULN_REFERENCES.equals(node); +392 } +393 +394 /** +395 * Checks if the handler is at the REFERENCE node. +396 * +397 * @return true or false +398 */ +399 public boolean isVulnReferenceNode() { +400 return VULN_REFERENCE.equals(node); +401 } +402 +403 /** +404 * Checks if the handler is at the VULN_SOURCE node. +405 * +406 * @return true or false +407 */ +408 public boolean isVulnSourceNode() { +409 return VULN_SOURCE.equals(node); +410 } +411 +412 /** +413 * Checks if the handler is at the VULN_SUMMARY node. +414 * +415 * @return true or false +416 */ +417 public boolean isVulnSummaryNode() { +418 return VULN_SUMMARY.equals(node); +419 } +420 +421 /** +422 * Checks if the handler is at the VULN_CWE node. +423 * +424 * @return true or false +425 */ +426 public boolean isVulnCWENode() { +427 return VULN_CWE.equals(node); +428 } +429 +430 /** +431 * Checks if the handler is at the CVSS_SCORE node. +432 * +433 * @return true or false +434 */ +435 public boolean isCVSSScoreNode() { +436 return CVSS_SCORE.equals(node); +437 } +438 +439 /** +440 * Checks if the handler is at the CVSS_ACCESS_VECTOR node. +441 * +442 * @return true or false +443 */ +444 public boolean isCVSSAccessVectorNode() { +445 return CVSS_ACCESS_VECTOR.equals(node); +446 } +447 +448 /** +449 * Checks if the handler is at the CVSS_ACCESS_COMPLEXITY node. +450 * +451 * @return true or false +452 */ +453 public boolean isCVSSAccessComplexityNode() { +454 return CVSS_ACCESS_COMPLEXITY.equals(node); +455 } +456 +457 /** +458 * Checks if the handler is at the CVSS_AUTHENTICATION node. +459 * +460 * @return true or false +461 */ +462 public boolean isCVSSAuthenticationNode() { +463 return CVSS_AUTHENTICATION.equals(node); +464 } +465 +466 /** +467 * Checks if the handler is at the CVSS_CONFIDENTIALITY_IMPACT node. +468 * +469 * @return true or false +470 */ +471 public boolean isCVSSConfidentialityImpactNode() { +472 return CVSS_CONFIDENTIALITY_IMPACT.equals(node); +473 } +474 +475 /** +476 * Checks if the handler is at the CVSS_INTEGRITY_IMPACT node. +477 * +478 * @return true or false +479 */ +480 public boolean isCVSSIntegrityImpactNode() { +481 return CVSS_INTEGRITY_IMPACT.equals(node); +482 } +483 +484 /** +485 * Checks if the handler is at the CVSS_AVAILABILITY_IMPACT node. +486 * +487 * @return true or false +488 */ +489 public boolean isCVSSAvailabilityImpactNode() { +490 return CVSS_AVAILABILITY_IMPACT.equals(node); +491 } +492 } +493 // </editor-fold> +494 }
      diff --git a/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html b/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html index b03ff3669..fbf5e5736 100644 --- a/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html index f7a120f0f..31786faa1 100644 --- a/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/xref/org/owasp/dependencycheck/data/update/package-frame.html b/xref/org/owasp/dependencycheck/data/update/package-frame.html index b10f2eb67..a5bc35458 100644 --- a/xref/org/owasp/dependencycheck/data/update/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/update/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update diff --git a/xref/org/owasp/dependencycheck/data/update/package-summary.html b/xref/org/owasp/dependencycheck/data/update/package-summary.html index 90c225760..9a922be2e 100644 --- a/xref/org/owasp/dependencycheck/data/update/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/update/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update diff --git a/xref/org/owasp/dependencycheck/dependency/Dependency.html b/xref/org/owasp/dependencycheck/dependency/Dependency.html index 141da3262..1b976840a 100644 --- a/xref/org/owasp/dependencycheck/dependency/Dependency.html +++ b/xref/org/owasp/dependencycheck/dependency/Dependency.html @@ -44,740 +44,783 @@ 36 import org.slf4j.LoggerFactory; 37 38 /** -39 * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about -40 * the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published, -41 * vulnerabilities associated with the program dependency. -42 * -43 * @author Jeremy Long -44 */ -45 public class Dependency implements Serializable, Comparable<Dependency> { -46 -47 /** -48 * The serial version UID for serialization. -49 */ -50 private static final long serialVersionUID = 1L; -51 /** -52 * The logger. -53 */ -54 private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class); -55 /** -56 * Used as starting point for generating the value in {@link #hashCode()}. -57 */ -58 private static final int MAGIC_HASH_INIT_VALUE = 3; -59 /** -60 * Used as a multiplier for generating the value in {@link #hashCode()}. -61 */ -62 private static final int MAGIC_HASH_MULTIPLIER = 47; -63 /** -64 * The actual file path of the dependency on disk. -65 */ -66 private String actualFilePath; -67 /** -68 * The file path to display. -69 */ -70 private String filePath; -71 /** -72 * The file name of the dependency. -73 */ -74 private String fileName; -75 /** -76 * The md5 hash of the dependency. -77 */ -78 private String md5sum; -79 /** -80 * The SHA1 hash of the dependency. -81 */ -82 private String sha1sum; -83 /** -84 * A list of Identifiers. -85 */ -86 private Set<Identifier> identifiers; -87 /** -88 * A collection of vendor evidence. -89 */ -90 private final EvidenceCollection vendorEvidence; +39 * A program dependency. This object is one of the core components within +40 * DependencyCheck. It is used to collect information about the dependency in +41 * the form of evidence. The Evidence is then used to determine if there are any +42 * known, published, vulnerabilities associated with the program dependency. +43 * +44 * @author Jeremy Long +45 */ +46 public class Dependency implements Serializable, Comparable<Dependency> { +47 +48 /** +49 * The serial version UID for serialization. +50 */ +51 private static final long serialVersionUID = 1L; +52 /** +53 * The logger. +54 */ +55 private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class); +56 /** +57 * Used as starting point for generating the value in {@link #hashCode()}. +58 */ +59 private static final int MAGIC_HASH_INIT_VALUE = 3; +60 /** +61 * Used as a multiplier for generating the value in {@link #hashCode()}. +62 */ +63 private static final int MAGIC_HASH_MULTIPLIER = 47; +64 /** +65 * The actual file path of the dependency on disk. +66 */ +67 private String actualFilePath; +68 /** +69 * The file path to display. +70 */ +71 private String filePath; +72 /** +73 * The file name of the dependency. +74 */ +75 private String fileName; +76 +77 /** +78 * The package path. +79 */ +80 private String packagePath; +81 +82 /** +83 * Returns the package path. +84 * +85 * @return the package path +86 */ +87 public String getPackagePath() { +88 return packagePath; +89 } +90 91 /** -92 * A collection of product evidence. -93 */ -94 private final EvidenceCollection productEvidence; -95 /** -96 * A collection of version evidence. -97 */ -98 private final EvidenceCollection versionEvidence; +92 * Sets the package path. +93 * +94 * @param packagePath the package path +95 */ +96 public void setPackagePath(String packagePath) { +97 this.packagePath = packagePath; +98 } 99 100 /** -101 * Constructs a new Dependency object. +101 * The md5 hash of the dependency. 102 */ -103 public Dependency() { -104 vendorEvidence = new EvidenceCollection(); -105 productEvidence = new EvidenceCollection(); -106 versionEvidence = new EvidenceCollection(); -107 identifiers = new TreeSet<Identifier>(); -108 vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); -109 suppressedIdentifiers = new TreeSet<Identifier>(); -110 suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); -111 } -112 -113 /** -114 * Constructs a new Dependency object. -115 * -116 * @param file the File to create the dependency object from. -117 */ -118 public Dependency(File file) { -119 this(); -120 this.actualFilePath = file.getAbsolutePath(); -121 this.filePath = this.actualFilePath; -122 this.fileName = file.getName(); -123 determineHashes(file); -124 } -125 -126 /** -127 * Returns the file name of the dependency. -128 * -129 * @return the file name of the dependency -130 */ -131 public String getFileName() { -132 return this.fileName; -133 } -134 -135 /** -136 * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I -137 * could not get the replace to work in the template itself. -138 * -139 * @return the file name of the dependency with the backslash escaped for use in JavaScript -140 */ -141 public String getFileNameForJavaScript() { -142 return this.fileName.replace("\\", "\\\\"); -143 } -144 -145 /** -146 * Sets the file name of the dependency. -147 * -148 * @param fileName the file name of the dependency -149 */ -150 public void setFileName(String fileName) { -151 this.fileName = fileName; -152 } -153 -154 /** -155 * Sets the actual file path of the dependency on disk. -156 * -157 * @param actualFilePath the file path of the dependency -158 */ -159 public void setActualFilePath(String actualFilePath) { -160 this.actualFilePath = actualFilePath; -161 if (this.sha1sum == null) { -162 final File file = new File(this.actualFilePath); -163 determineHashes(file); -164 } -165 } -166 -167 /** -168 * Gets the file path of the dependency. -169 * -170 * @return the file path of the dependency -171 */ -172 public String getActualFilePath() { -173 return this.actualFilePath; -174 } -175 -176 /** -177 * Gets a reference to the File object. -178 * -179 * @return the File object -180 */ -181 public File getActualFile() { -182 return new File(this.actualFilePath); -183 } -184 -185 /** -186 * Sets the file path of the dependency. -187 * -188 * @param filePath the file path of the dependency -189 */ -190 public void setFilePath(String filePath) { -191 this.filePath = filePath; -192 } -193 -194 /** -195 * The file name to display in reports. -196 */ -197 private String displayName = null; -198 -199 /** -200 * Sets the file name to display in reports. -201 * -202 * @param displayName the name to display -203 */ -204 public void setDisplayFileName(String displayName) { -205 this.displayName = displayName; -206 } -207 -208 /** -209 * Returns the file name to display in reports; if no display file name has been set it will default to the actual file name. -210 * -211 * @return the file name to display -212 */ -213 public String getDisplayFileName() { -214 if (displayName == null) { -215 return this.fileName; -216 } -217 return this.displayName; -218 } -219 -220 /** -221 * <p> -222 * Gets the file path of the dependency.</p> -223 * <p> -224 * <b>NOTE:</b> This may not be the actual path of the file on disk. The actual path of the file on disk can be obtained via -225 * the getActualFilePath().</p> -226 * -227 * @return the file path of the dependency -228 */ -229 public String getFilePath() { -230 return this.filePath; -231 } -232 -233 /** -234 * Returns the MD5 Checksum of the dependency file. -235 * -236 * @return the MD5 Checksum -237 */ -238 public String getMd5sum() { -239 return this.md5sum; -240 } -241 -242 /** -243 * Sets the MD5 Checksum of the dependency. -244 * -245 * @param md5sum the MD5 Checksum -246 */ -247 public void setMd5sum(String md5sum) { -248 this.md5sum = md5sum; -249 } -250 -251 /** -252 * Returns the SHA1 Checksum of the dependency. -253 * -254 * @return the SHA1 Checksum -255 */ -256 public String getSha1sum() { -257 return this.sha1sum; -258 } -259 -260 /** -261 * Sets the SHA1 Checksum of the dependency. -262 * -263 * @param sha1sum the SHA1 Checksum -264 */ -265 public void setSha1sum(String sha1sum) { -266 this.sha1sum = sha1sum; -267 } -268 -269 /** -270 * Returns a List of Identifiers. -271 * -272 * @return an ArrayList of Identifiers -273 */ -274 public Set<Identifier> getIdentifiers() { -275 return this.identifiers; -276 } -277 -278 /** -279 * Sets a List of Identifiers. -280 * -281 * @param identifiers A list of Identifiers -282 */ -283 public void setIdentifiers(Set<Identifier> identifiers) { -284 this.identifiers = identifiers; -285 } -286 -287 /** -288 * Adds an entry to the list of detected Identifiers for the dependency file. -289 * -290 * @param type the type of identifier (such as CPE) -291 * @param value the value of the identifier -292 * @param url the URL of the identifier -293 */ -294 public void addIdentifier(String type, String value, String url) { -295 final Identifier i = new Identifier(type, value, url); -296 this.identifiers.add(i); -297 } -298 -299 /** -300 * Adds an entry to the list of detected Identifiers for the dependency file. -301 * -302 * @param type the type of identifier (such as CPE) -303 * @param value the value of the identifier -304 * @param url the URL of the identifier -305 * @param confidence the confidence in the Identifier being accurate +103 private String md5sum; +104 /** +105 * The SHA1 hash of the dependency. +106 */ +107 private String sha1sum; +108 /** +109 * A list of Identifiers. +110 */ +111 private Set<Identifier> identifiers; +112 /** +113 * A collection of vendor evidence. +114 */ +115 private final EvidenceCollection vendorEvidence; +116 /** +117 * A collection of product evidence. +118 */ +119 private final EvidenceCollection productEvidence; +120 /** +121 * A collection of version evidence. +122 */ +123 private final EvidenceCollection versionEvidence; +124 +125 /** +126 * Constructs a new Dependency object. +127 */ +128 public Dependency() { +129 vendorEvidence = new EvidenceCollection(); +130 productEvidence = new EvidenceCollection(); +131 versionEvidence = new EvidenceCollection(); +132 identifiers = new TreeSet<Identifier>(); +133 vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); +134 suppressedIdentifiers = new TreeSet<Identifier>(); +135 suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); +136 } +137 +138 /** +139 * Constructs a new Dependency object. +140 * +141 * @param file the File to create the dependency object from. +142 */ +143 public Dependency(File file) { +144 this(); +145 this.actualFilePath = file.getAbsolutePath(); +146 this.filePath = this.actualFilePath; +147 this.fileName = file.getName(); +148 this.packagePath = filePath; +149 determineHashes(file); +150 } +151 +152 /** +153 * Returns the file name of the dependency. +154 * +155 * @return the file name of the dependency +156 */ +157 public String getFileName() { +158 return this.fileName; +159 } +160 +161 /** +162 * Returns the file name of the dependency with the backslash escaped for +163 * use in JavaScript. This is a complete hack as I could not get the replace +164 * to work in the template itself. +165 * +166 * @return the file name of the dependency with the backslash escaped for +167 * use in JavaScript +168 */ +169 public String getFileNameForJavaScript() { +170 return this.fileName.replace("\\", "\\\\"); +171 } +172 +173 /** +174 * Sets the file name of the dependency. +175 * +176 * @param fileName the file name of the dependency +177 */ +178 public void setFileName(String fileName) { +179 this.fileName = fileName; +180 } +181 +182 /** +183 * Sets the actual file path of the dependency on disk. +184 * +185 * @param actualFilePath the file path of the dependency +186 */ +187 public void setActualFilePath(String actualFilePath) { +188 this.actualFilePath = actualFilePath; +189 if (this.sha1sum == null) { +190 final File file = new File(this.actualFilePath); +191 determineHashes(file); +192 } +193 } +194 +195 /** +196 * Gets the file path of the dependency. +197 * +198 * @return the file path of the dependency +199 */ +200 public String getActualFilePath() { +201 return this.actualFilePath; +202 } +203 +204 /** +205 * Gets a reference to the File object. +206 * +207 * @return the File object +208 */ +209 public File getActualFile() { +210 return new File(this.actualFilePath); +211 } +212 +213 /** +214 * Sets the file path of the dependency. +215 * +216 * @param filePath the file path of the dependency +217 */ +218 public void setFilePath(String filePath) { +219 if (this.packagePath == null || this.packagePath.equals(this.filePath)) { +220 this.packagePath = filePath; +221 } +222 this.filePath = filePath; +223 } +224 +225 /** +226 * The file name to display in reports. +227 */ +228 private String displayName = null; +229 +230 /** +231 * Sets the file name to display in reports. +232 * +233 * @param displayName the name to display +234 */ +235 public void setDisplayFileName(String displayName) { +236 this.displayName = displayName; +237 } +238 +239 /** +240 * Returns the file name to display in reports; if no display file name has +241 * been set it will default to the actual file name. +242 * +243 * @return the file name to display +244 */ +245 public String getDisplayFileName() { +246 if (displayName == null) { +247 return this.fileName; +248 } +249 return this.displayName; +250 } +251 +252 /** +253 * <p> +254 * Gets the file path of the dependency.</p> +255 * <p> +256 * <b>NOTE:</b> This may not be the actual path of the file on disk. The +257 * actual path of the file on disk can be obtained via the +258 * getActualFilePath().</p> +259 * +260 * @return the file path of the dependency +261 */ +262 public String getFilePath() { +263 return this.filePath; +264 } +265 +266 /** +267 * Returns the MD5 Checksum of the dependency file. +268 * +269 * @return the MD5 Checksum +270 */ +271 public String getMd5sum() { +272 return this.md5sum; +273 } +274 +275 /** +276 * Sets the MD5 Checksum of the dependency. +277 * +278 * @param md5sum the MD5 Checksum +279 */ +280 public void setMd5sum(String md5sum) { +281 this.md5sum = md5sum; +282 } +283 +284 /** +285 * Returns the SHA1 Checksum of the dependency. +286 * +287 * @return the SHA1 Checksum +288 */ +289 public String getSha1sum() { +290 return this.sha1sum; +291 } +292 +293 /** +294 * Sets the SHA1 Checksum of the dependency. +295 * +296 * @param sha1sum the SHA1 Checksum +297 */ +298 public void setSha1sum(String sha1sum) { +299 this.sha1sum = sha1sum; +300 } +301 +302 /** +303 * Returns a List of Identifiers. +304 * +305 * @return an ArrayList of Identifiers 306 */ -307 public void addIdentifier(String type, String value, String url, Confidence confidence) { -308 final Identifier i = new Identifier(type, value, url); -309 i.setConfidence(confidence); -310 this.identifiers.add(i); -311 } -312 -313 /** -314 * Adds the maven artifact as evidence. -315 * -316 * @param source The source of the evidence -317 * @param mavenArtifact The maven artifact -318 * @param confidence The confidence level of this evidence -319 */ -320 public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) { -321 if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) { -322 this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence); -323 } -324 if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) { -325 this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence); -326 } -327 if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) { -328 this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence); -329 } -330 if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) { -331 boolean found = false; -332 for (Identifier i : this.getIdentifiers()) { -333 if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) { -334 found = true; -335 i.setConfidence(Confidence.HIGHEST); -336 final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22"; -337 i.setUrl(url); -338 //i.setUrl(mavenArtifact.getArtifactUrl()); -339 LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue()); -340 break; -341 } -342 } -343 if (!found) { -344 LOGGER.debug("Adding new maven identifier {}", mavenArtifact); -345 this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST); -346 } -347 } -348 } -349 -350 /** -351 * Adds an entry to the list of detected Identifiers for the dependency file. -352 * -353 * @param identifier the identifier to add +307 public Set<Identifier> getIdentifiers() { +308 return this.identifiers; +309 } +310 +311 /** +312 * Sets a List of Identifiers. +313 * +314 * @param identifiers A list of Identifiers +315 */ +316 public void setIdentifiers(Set<Identifier> identifiers) { +317 this.identifiers = identifiers; +318 } +319 +320 /** +321 * Adds an entry to the list of detected Identifiers for the dependency +322 * file. +323 * +324 * @param type the type of identifier (such as CPE) +325 * @param value the value of the identifier +326 * @param url the URL of the identifier +327 */ +328 public void addIdentifier(String type, String value, String url) { +329 final Identifier i = new Identifier(type, value, url); +330 this.identifiers.add(i); +331 } +332 +333 /** +334 * Adds an entry to the list of detected Identifiers for the dependency +335 * file. +336 * +337 * @param type the type of identifier (such as CPE) +338 * @param value the value of the identifier +339 * @param url the URL of the identifier +340 * @param confidence the confidence in the Identifier being accurate +341 */ +342 public void addIdentifier(String type, String value, String url, Confidence confidence) { +343 final Identifier i = new Identifier(type, value, url); +344 i.setConfidence(confidence); +345 this.identifiers.add(i); +346 } +347 +348 /** +349 * Adds the maven artifact as evidence. +350 * +351 * @param source The source of the evidence +352 * @param mavenArtifact The maven artifact +353 * @param confidence The confidence level of this evidence 354 */ -355 public void addIdentifier(Identifier identifier) { -356 this.identifiers.add(identifier); -357 } -358 -359 /** -360 * A set of identifiers that have been suppressed. -361 */ -362 private Set<Identifier> suppressedIdentifiers; -363 -364 /** -365 * Get the value of suppressedIdentifiers. -366 * -367 * @return the value of suppressedIdentifiers -368 */ -369 public Set<Identifier> getSuppressedIdentifiers() { -370 return suppressedIdentifiers; -371 } -372 -373 /** -374 * Set the value of suppressedIdentifiers. -375 * -376 * @param suppressedIdentifiers new value of suppressedIdentifiers -377 */ -378 public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) { -379 this.suppressedIdentifiers = suppressedIdentifiers; -380 } -381 -382 /** -383 * Adds an identifier to the list of suppressed identifiers. -384 * -385 * @param identifier an identifier that was suppressed. -386 */ -387 public void addSuppressedIdentifier(Identifier identifier) { -388 this.suppressedIdentifiers.add(identifier); -389 } -390 -391 /** -392 * A set of vulnerabilities that have been suppressed. -393 */ -394 private SortedSet<Vulnerability> suppressedVulnerabilities; -395 -396 /** -397 * Get the value of suppressedVulnerabilities. -398 * -399 * @return the value of suppressedVulnerabilities -400 */ -401 public SortedSet<Vulnerability> getSuppressedVulnerabilities() { -402 return suppressedVulnerabilities; -403 } -404 -405 /** -406 * Set the value of suppressedVulnerabilities. -407 * -408 * @param suppressedVulnerabilities new value of suppressedVulnerabilities -409 */ -410 public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) { -411 this.suppressedVulnerabilities = suppressedVulnerabilities; -412 } -413 -414 /** -415 * Adds a vulnerability to the set of suppressed vulnerabilities. -416 * -417 * @param vulnerability the vulnerability that was suppressed -418 */ -419 public void addSuppressedVulnerability(Vulnerability vulnerability) { -420 this.suppressedVulnerabilities.add(vulnerability); -421 } -422 -423 /** -424 * Returns the evidence used to identify this dependency. -425 * -426 * @return an EvidenceCollection. -427 */ -428 public EvidenceCollection getEvidence() { -429 return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence); -430 } +355 public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) { +356 if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) { +357 this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence); +358 } +359 if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) { +360 this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence); +361 } +362 if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) { +363 this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence); +364 } +365 if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) { +366 boolean found = false; +367 for (Identifier i : this.getIdentifiers()) { +368 if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) { +369 found = true; +370 i.setConfidence(Confidence.HIGHEST); +371 final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22"; +372 i.setUrl(url); +373 //i.setUrl(mavenArtifact.getArtifactUrl()); +374 LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue()); +375 break; +376 } +377 } +378 if (!found) { +379 LOGGER.debug("Adding new maven identifier {}", mavenArtifact); +380 this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST); +381 } +382 } +383 } +384 +385 /** +386 * Adds an entry to the list of detected Identifiers for the dependency +387 * file. +388 * +389 * @param identifier the identifier to add +390 */ +391 public void addIdentifier(Identifier identifier) { +392 this.identifiers.add(identifier); +393 } +394 +395 /** +396 * A set of identifiers that have been suppressed. +397 */ +398 private Set<Identifier> suppressedIdentifiers; +399 +400 /** +401 * Get the value of suppressedIdentifiers. +402 * +403 * @return the value of suppressedIdentifiers +404 */ +405 public Set<Identifier> getSuppressedIdentifiers() { +406 return suppressedIdentifiers; +407 } +408 +409 /** +410 * Set the value of suppressedIdentifiers. +411 * +412 * @param suppressedIdentifiers new value of suppressedIdentifiers +413 */ +414 public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) { +415 this.suppressedIdentifiers = suppressedIdentifiers; +416 } +417 +418 /** +419 * Adds an identifier to the list of suppressed identifiers. +420 * +421 * @param identifier an identifier that was suppressed. +422 */ +423 public void addSuppressedIdentifier(Identifier identifier) { +424 this.suppressedIdentifiers.add(identifier); +425 } +426 +427 /** +428 * A set of vulnerabilities that have been suppressed. +429 */ +430 private SortedSet<Vulnerability> suppressedVulnerabilities; 431 432 /** -433 * Returns the evidence used to identify this dependency. +433 * Get the value of suppressedVulnerabilities. 434 * -435 * @return an EvidenceCollection. +435 * @return the value of suppressedVulnerabilities 436 */ -437 public Set<Evidence> getEvidenceForDisplay() { -438 return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence); +437 public SortedSet<Vulnerability> getSuppressedVulnerabilities() { +438 return suppressedVulnerabilities; 439 } 440 441 /** -442 * Returns the evidence used to identify this dependency. +442 * Set the value of suppressedVulnerabilities. 443 * -444 * @return an EvidenceCollection. +444 * @param suppressedVulnerabilities new value of suppressedVulnerabilities 445 */ -446 public EvidenceCollection getEvidenceUsed() { -447 return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence); +446 public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) { +447 this.suppressedVulnerabilities = suppressedVulnerabilities; 448 } 449 450 /** -451 * Gets the Vendor Evidence. +451 * Adds a vulnerability to the set of suppressed vulnerabilities. 452 * -453 * @return an EvidenceCollection. +453 * @param vulnerability the vulnerability that was suppressed 454 */ -455 public EvidenceCollection getVendorEvidence() { -456 return this.vendorEvidence; +455 public void addSuppressedVulnerability(Vulnerability vulnerability) { +456 this.suppressedVulnerabilities.add(vulnerability); 457 } 458 459 /** -460 * Gets the Product Evidence. +460 * Returns the evidence used to identify this dependency. 461 * 462 * @return an EvidenceCollection. 463 */ -464 public EvidenceCollection getProductEvidence() { -465 return this.productEvidence; +464 public EvidenceCollection getEvidence() { +465 return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence); 466 } 467 468 /** -469 * Gets the Version Evidence. +469 * Returns the evidence used to identify this dependency. 470 * 471 * @return an EvidenceCollection. 472 */ -473 public EvidenceCollection getVersionEvidence() { -474 return this.versionEvidence; +473 public Set<Evidence> getEvidenceForDisplay() { +474 return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence); 475 } 476 477 /** -478 * The description of the JAR file. -479 */ -480 private String description; -481 -482 /** -483 * Get the value of description. -484 * -485 * @return the value of description -486 */ -487 public String getDescription() { -488 return description; -489 } -490 -491 /** -492 * Set the value of description. -493 * -494 * @param description new value of description -495 */ -496 public void setDescription(String description) { -497 this.description = description; -498 } -499 -500 /** -501 * The license that this dependency uses. -502 */ -503 private String license; -504 -505 /** -506 * Get the value of license. -507 * -508 * @return the value of license -509 */ -510 public String getLicense() { -511 return license; -512 } -513 -514 /** -515 * Set the value of license. -516 * -517 * @param license new value of license -518 */ -519 public void setLicense(String license) { -520 this.license = license; -521 } -522 -523 /** -524 * A list of vulnerabilities for this dependency. -525 */ -526 private SortedSet<Vulnerability> vulnerabilities; -527 -528 /** -529 * Get the list of vulnerabilities. -530 * -531 * @return the list of vulnerabilities -532 */ -533 public SortedSet<Vulnerability> getVulnerabilities() { -534 return vulnerabilities; -535 } -536 -537 /** -538 * Set the value of vulnerabilities. -539 * -540 * @param vulnerabilities new value of vulnerabilities -541 */ -542 public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) { -543 this.vulnerabilities = vulnerabilities; -544 } -545 -546 /** -547 * Determines the sha1 and md5 sum for the given file. -548 * -549 * @param file the file to create checksums for -550 */ -551 private void determineHashes(File file) { -552 String md5 = null; -553 String sha1 = null; -554 try { -555 md5 = Checksum.getMD5Checksum(file); -556 sha1 = Checksum.getSHA1Checksum(file); -557 } catch (IOException ex) { -558 LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName()); -559 LOGGER.debug("", ex); -560 } catch (NoSuchAlgorithmException ex) { -561 LOGGER.warn("Unable to use MD5 of SHA1 checksums."); -562 LOGGER.debug("", ex); -563 } -564 this.setMd5sum(md5); -565 this.setSha1sum(sha1); -566 } -567 -568 /** -569 * Adds a vulnerability to the dependency. -570 * -571 * @param vulnerability a vulnerability outlining a vulnerability. -572 */ -573 public void addVulnerability(Vulnerability vulnerability) { -574 this.vulnerabilities.add(vulnerability); -575 } -576 -577 /** -578 * A collection of related dependencies. -579 */ -580 private Set<Dependency> relatedDependencies = new TreeSet<Dependency>(); +478 * Returns the evidence used to identify this dependency. +479 * +480 * @return an EvidenceCollection. +481 */ +482 public EvidenceCollection getEvidenceUsed() { +483 return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence); +484 } +485 +486 /** +487 * Gets the Vendor Evidence. +488 * +489 * @return an EvidenceCollection. +490 */ +491 public EvidenceCollection getVendorEvidence() { +492 return this.vendorEvidence; +493 } +494 +495 /** +496 * Gets the Product Evidence. +497 * +498 * @return an EvidenceCollection. +499 */ +500 public EvidenceCollection getProductEvidence() { +501 return this.productEvidence; +502 } +503 +504 /** +505 * Gets the Version Evidence. +506 * +507 * @return an EvidenceCollection. +508 */ +509 public EvidenceCollection getVersionEvidence() { +510 return this.versionEvidence; +511 } +512 +513 /** +514 * The description of the JAR file. +515 */ +516 private String description; +517 +518 /** +519 * Get the value of description. +520 * +521 * @return the value of description +522 */ +523 public String getDescription() { +524 return description; +525 } +526 +527 /** +528 * Set the value of description. +529 * +530 * @param description new value of description +531 */ +532 public void setDescription(String description) { +533 this.description = description; +534 } +535 +536 /** +537 * The license that this dependency uses. +538 */ +539 private String license; +540 +541 /** +542 * Get the value of license. +543 * +544 * @return the value of license +545 */ +546 public String getLicense() { +547 return license; +548 } +549 +550 /** +551 * Set the value of license. +552 * +553 * @param license new value of license +554 */ +555 public void setLicense(String license) { +556 this.license = license; +557 } +558 +559 /** +560 * A list of vulnerabilities for this dependency. +561 */ +562 private SortedSet<Vulnerability> vulnerabilities; +563 +564 /** +565 * Get the list of vulnerabilities. +566 * +567 * @return the list of vulnerabilities +568 */ +569 public SortedSet<Vulnerability> getVulnerabilities() { +570 return vulnerabilities; +571 } +572 +573 /** +574 * Set the value of vulnerabilities. +575 * +576 * @param vulnerabilities new value of vulnerabilities +577 */ +578 public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) { +579 this.vulnerabilities = vulnerabilities; +580 } 581 582 /** -583 * Get the value of {@link #relatedDependencies}. This field is used to collect other dependencies which really represent the -584 * same dependency, and may be presented as one item in reports. -585 * -586 * @return the value of relatedDependencies -587 */ -588 public Set<Dependency> getRelatedDependencies() { -589 return relatedDependencies; -590 } -591 -592 /** -593 * A list of projects that reference this dependency. -594 */ -595 private Set<String> projectReferences = new HashSet<String>(); -596 -597 /** -598 * Get the value of projectReferences. -599 * -600 * @return the value of projectReferences -601 */ -602 public Set<String> getProjectReferences() { -603 return projectReferences; -604 } -605 -606 /** -607 * Set the value of projectReferences. -608 * -609 * @param projectReferences new value of projectReferences -610 */ -611 public void setProjectReferences(Set<String> projectReferences) { -612 this.projectReferences = projectReferences; -613 } -614 -615 /** -616 * Adds a project reference. -617 * -618 * @param projectReference a project reference -619 */ -620 public void addProjectReference(String projectReference) { -621 this.projectReferences.add(projectReference); -622 } -623 -624 /** -625 * Add a collection of project reference. -626 * -627 * @param projectReferences a set of project references -628 */ -629 public void addAllProjectReferences(Set<String> projectReferences) { -630 this.projectReferences.addAll(projectReferences); -631 } -632 -633 /** -634 * Set the value of relatedDependencies. -635 * -636 * @param relatedDependencies new value of relatedDependencies -637 */ -638 public void setRelatedDependencies(Set<Dependency> relatedDependencies) { -639 this.relatedDependencies = relatedDependencies; -640 } -641 -642 /** -643 * Adds a related dependency. The internal collection is normally a {@link java.util.TreeSet}, which relies on -644 * {@link #compareTo(Dependency)}. A consequence of this is that if you attempt to add a dependency with the same file path -645 * (modulo character case) as one that is already in the collection, it won't get added. -646 * -647 * @param dependency a reference to the related dependency -648 */ -649 public void addRelatedDependency(Dependency dependency) { -650 if (this == dependency) { -651 LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here " -652 + "https://github.com/jeremylong/DependencyCheck/issues/172"); -653 LOGGER.debug("this: {}", this); -654 LOGGER.debug("dependency: {}", dependency); -655 } else if (!relatedDependencies.add(dependency)) { -656 LOGGER.debug("Failed to add dependency, likely due to referencing the same file as another dependency in the set."); -657 LOGGER.debug("this: {}", this); -658 LOGGER.debug("dependency: {}", dependency); -659 } -660 } -661 -662 /** -663 * A list of available versions. -664 */ -665 private List<String> availableVersions = new ArrayList<String>(); -666 -667 /** -668 * Get the value of availableVersions. -669 * -670 * @return the value of availableVersions -671 */ -672 public List<String> getAvailableVersions() { -673 return availableVersions; -674 } -675 -676 /** -677 * Set the value of availableVersions. -678 * -679 * @param availableVersions new value of availableVersions -680 */ -681 public void setAvailableVersions(List<String> availableVersions) { -682 this.availableVersions = availableVersions; -683 } -684 -685 /** -686 * Adds a version to the available version list. -687 * -688 * @param version the version to add to the list -689 */ -690 public void addAvailableVersion(String version) { -691 this.availableVersions.add(version); -692 } -693 -694 /** -695 * Implementation of the Comparable&lt;Dependency&gt; interface. The comparison is solely based on the file path. -696 * -697 * @param o a dependency to compare -698 * @return an integer representing the natural ordering -699 */ -700 @Override -701 public int compareTo(Dependency o) { -702 return this.getFilePath().compareToIgnoreCase(o.getFilePath()); -703 } -704 -705 /** -706 * Implementation of the equals method. -707 * -708 * @param obj the object to compare -709 * @return true if the objects are equal, otherwise false +583 * Determines the sha1 and md5 sum for the given file. +584 * +585 * @param file the file to create checksums for +586 */ +587 private void determineHashes(File file) { +588 String md5 = null; +589 String sha1 = null; +590 try { +591 md5 = Checksum.getMD5Checksum(file); +592 sha1 = Checksum.getSHA1Checksum(file); +593 } catch (IOException ex) { +594 LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName()); +595 LOGGER.debug("", ex); +596 } catch (NoSuchAlgorithmException ex) { +597 LOGGER.warn("Unable to use MD5 of SHA1 checksums."); +598 LOGGER.debug("", ex); +599 } +600 this.setMd5sum(md5); +601 this.setSha1sum(sha1); +602 } +603 +604 /** +605 * Adds a vulnerability to the dependency. +606 * +607 * @param vulnerability a vulnerability outlining a vulnerability. +608 */ +609 public void addVulnerability(Vulnerability vulnerability) { +610 this.vulnerabilities.add(vulnerability); +611 } +612 +613 /** +614 * A collection of related dependencies. +615 */ +616 private Set<Dependency> relatedDependencies = new TreeSet<Dependency>(); +617 +618 /** +619 * Get the value of {@link #relatedDependencies}. This field is used to +620 * collect other dependencies which really represent the same dependency, +621 * and may be presented as one item in reports. +622 * +623 * @return the value of relatedDependencies +624 */ +625 public Set<Dependency> getRelatedDependencies() { +626 return relatedDependencies; +627 } +628 +629 /** +630 * A list of projects that reference this dependency. +631 */ +632 private Set<String> projectReferences = new HashSet<String>(); +633 +634 /** +635 * Get the value of projectReferences. +636 * +637 * @return the value of projectReferences +638 */ +639 public Set<String> getProjectReferences() { +640 return projectReferences; +641 } +642 +643 /** +644 * Set the value of projectReferences. +645 * +646 * @param projectReferences new value of projectReferences +647 */ +648 public void setProjectReferences(Set<String> projectReferences) { +649 this.projectReferences = projectReferences; +650 } +651 +652 /** +653 * Adds a project reference. +654 * +655 * @param projectReference a project reference +656 */ +657 public void addProjectReference(String projectReference) { +658 this.projectReferences.add(projectReference); +659 } +660 +661 /** +662 * Add a collection of project reference. +663 * +664 * @param projectReferences a set of project references +665 */ +666 public void addAllProjectReferences(Set<String> projectReferences) { +667 this.projectReferences.addAll(projectReferences); +668 } +669 +670 /** +671 * Set the value of relatedDependencies. +672 * +673 * @param relatedDependencies new value of relatedDependencies +674 */ +675 public void setRelatedDependencies(Set<Dependency> relatedDependencies) { +676 this.relatedDependencies = relatedDependencies; +677 } +678 +679 /** +680 * Adds a related dependency. The internal collection is normally a +681 * {@link java.util.TreeSet}, which relies on +682 * {@link #compareTo(Dependency)}. A consequence of this is that if you +683 * attempt to add a dependency with the same file path (modulo character +684 * case) as one that is already in the collection, it won't get added. +685 * +686 * @param dependency a reference to the related dependency +687 */ +688 public void addRelatedDependency(Dependency dependency) { +689 if (this == dependency) { +690 LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here " +691 + "https://github.com/jeremylong/DependencyCheck/issues/172"); +692 LOGGER.debug("this: {}", this); +693 LOGGER.debug("dependency: {}", dependency); +694 } else if (!relatedDependencies.add(dependency)) { +695 LOGGER.debug("Failed to add dependency, likely due to referencing the same file as another dependency in the set."); +696 LOGGER.debug("this: {}", this); +697 LOGGER.debug("dependency: {}", dependency); +698 } +699 } +700 +701 /** +702 * A list of available versions. +703 */ +704 private List<String> availableVersions = new ArrayList<String>(); +705 +706 /** +707 * Get the value of availableVersions. +708 * +709 * @return the value of availableVersions 710 */ -711 @Override -712 public boolean equals(Object obj) { -713 if (obj == null || getClass() != obj.getClass()) { -714 return false; -715 } -716 final Dependency other = (Dependency) obj; -717 return new EqualsBuilder() -718 .appendSuper(super.equals(obj)) -719 .append(this.actualFilePath, other.actualFilePath) -720 .append(this.filePath, other.filePath) -721 .append(this.fileName, other.fileName) -722 .append(this.md5sum, other.md5sum) -723 .append(this.sha1sum, other.sha1sum) -724 .append(this.identifiers, other.identifiers) -725 .append(this.vendorEvidence, other.vendorEvidence) -726 .append(this.productEvidence, other.productEvidence) -727 .append(this.versionEvidence, other.versionEvidence) -728 .append(this.description, other.description) -729 .append(this.license, other.license) -730 .append(this.vulnerabilities, other.vulnerabilities) -731 //.append(this.relatedDependencies, other.relatedDependencies) -732 .append(this.projectReferences, other.projectReferences) -733 .append(this.availableVersions, other.availableVersions) -734 .isEquals(); -735 } -736 -737 /** -738 * Generates the HashCode. -739 * -740 * @return the HashCode -741 */ -742 @Override -743 public int hashCode() { -744 return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER) -745 .append(actualFilePath) -746 .append(filePath) -747 .append(fileName) -748 .append(md5sum) -749 .append(sha1sum) -750 .append(identifiers) -751 .append(vendorEvidence) -752 .append(productEvidence) -753 .append(versionEvidence) -754 .append(description) -755 .append(license) -756 .append(vulnerabilities) -757 //.append(relatedDependencies) -758 .append(projectReferences) -759 .append(availableVersions) -760 .toHashCode(); -761 } -762 -763 /** -764 * Standard toString() implementation showing the filename, actualFilePath, and filePath. -765 * -766 * @return the string representation of the file -767 */ -768 @Override -769 public String toString() { -770 return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}"; -771 } -772 } +711 public List<String> getAvailableVersions() { +712 return availableVersions; +713 } +714 +715 /** +716 * Set the value of availableVersions. +717 * +718 * @param availableVersions new value of availableVersions +719 */ +720 public void setAvailableVersions(List<String> availableVersions) { +721 this.availableVersions = availableVersions; +722 } +723 +724 /** +725 * Adds a version to the available version list. +726 * +727 * @param version the version to add to the list +728 */ +729 public void addAvailableVersion(String version) { +730 this.availableVersions.add(version); +731 } +732 +733 /** +734 * Implementation of the Comparable&lt;Dependency&gt; interface. The +735 * comparison is solely based on the file path. +736 * +737 * @param o a dependency to compare +738 * @return an integer representing the natural ordering +739 */ +740 @Override +741 public int compareTo(Dependency o) { +742 return this.getFilePath().compareToIgnoreCase(o.getFilePath()); +743 } +744 +745 /** +746 * Implementation of the equals method. +747 * +748 * @param obj the object to compare +749 * @return true if the objects are equal, otherwise false +750 */ +751 @Override +752 public boolean equals(Object obj) { +753 if (obj == null || getClass() != obj.getClass()) { +754 return false; +755 } +756 final Dependency other = (Dependency) obj; +757 return new EqualsBuilder() +758 .appendSuper(super.equals(obj)) +759 .append(this.actualFilePath, other.actualFilePath) +760 .append(this.filePath, other.filePath) +761 .append(this.fileName, other.fileName) +762 .append(this.packagePath, other.packagePath) +763 .append(this.md5sum, other.md5sum) +764 .append(this.sha1sum, other.sha1sum) +765 .append(this.identifiers, other.identifiers) +766 .append(this.vendorEvidence, other.vendorEvidence) +767 .append(this.productEvidence, other.productEvidence) +768 .append(this.versionEvidence, other.versionEvidence) +769 .append(this.description, other.description) +770 .append(this.license, other.license) +771 .append(this.vulnerabilities, other.vulnerabilities) +772 //.append(this.relatedDependencies, other.relatedDependencies) +773 .append(this.projectReferences, other.projectReferences) +774 .append(this.availableVersions, other.availableVersions) +775 .isEquals(); +776 } +777 +778 /** +779 * Generates the HashCode. +780 * +781 * @return the HashCode +782 */ +783 @Override +784 public int hashCode() { +785 return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER) +786 .append(actualFilePath) +787 .append(filePath) +788 .append(fileName) +789 .append(md5sum) +790 .append(sha1sum) +791 .append(identifiers) +792 .append(vendorEvidence) +793 .append(productEvidence) +794 .append(versionEvidence) +795 .append(description) +796 .append(license) +797 .append(vulnerabilities) +798 //.append(relatedDependencies) +799 .append(projectReferences) +800 .append(availableVersions) +801 .toHashCode(); +802 } +803 +804 /** +805 * Standard toString() implementation showing the filename, actualFilePath, +806 * and filePath. +807 * +808 * @return the string representation of the file +809 */ +810 @Override +811 public String toString() { +812 return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath +813 + "', filePath='" + filePath + "', packagePath='" + packagePath + "'}"; +814 } +815 }
      diff --git a/xref/org/owasp/dependencycheck/dependency/Reference.html b/xref/org/owasp/dependencycheck/dependency/Reference.html index 4bb97c302..2230c6e7a 100644 --- a/xref/org/owasp/dependencycheck/dependency/Reference.html +++ b/xref/org/owasp/dependencycheck/dependency/Reference.html @@ -28,136 +28,142 @@ 20 import java.io.Serializable; 21 22 /** -23 * An external reference for a vulnerability. This contains a name, URL, and a source. -24 * -25 * @author Jeremy Long -26 */ -27 public class Reference implements Serializable, Comparable<Reference> { -28 -29 /** -30 * the serial version uid. -31 */ -32 private static final long serialVersionUID = -3444464824563008021L; -33 /** -34 * The name of the reference. -35 */ -36 private String name; -37 -38 /** -39 * Get the value of name. -40 * -41 * @return the value of name -42 */ -43 public String getName() { -44 return name; -45 } -46 -47 /** -48 * Set the value of name. -49 * -50 * @param name new value of name -51 */ -52 public void setName(String name) { -53 this.name = name; -54 } -55 /** -56 * the url for the reference. -57 */ -58 private String url; -59 -60 /** -61 * Get the value of url. -62 * -63 * @return the value of url -64 */ -65 public String getUrl() { -66 return url; -67 } -68 -69 /** -70 * Set the value of url. -71 * -72 * @param url new value of url -73 */ -74 public void setUrl(String url) { -75 this.url = url; -76 } -77 /** -78 * the source of the reference. -79 */ -80 private String source; -81 -82 /** -83 * Get the value of source. -84 * -85 * @return the value of source -86 */ -87 public String getSource() { -88 return source; -89 } -90 -91 /** -92 * Set the value of source. -93 * -94 * @param source new value of source -95 */ -96 public void setSource(String source) { -97 this.source = source; -98 } -99 -100 @Override -101 public boolean equals(Object obj) { -102 if (obj == null) { -103 return false; -104 } -105 if (getClass() != obj.getClass()) { -106 return false; -107 } -108 final Reference other = (Reference) obj; -109 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { -110 return false; -111 } -112 if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) { -113 return false; -114 } -115 if ((this.source == null) ? (other.source != null) : !this.source.equals(other.source)) { +23 * An external reference for a vulnerability. This contains a name, URL, and a +24 * source. +25 * +26 * @author Jeremy Long +27 */ +28 public class Reference implements Serializable, Comparable<Reference> { +29 +30 /** +31 * the serial version uid. +32 */ +33 private static final long serialVersionUID = -3444464824563008021L; +34 /** +35 * The name of the reference. +36 */ +37 private String name; +38 +39 /** +40 * Get the value of name. +41 * +42 * @return the value of name +43 */ +44 public String getName() { +45 return name; +46 } +47 +48 /** +49 * Set the value of name. +50 * +51 * @param name new value of name +52 */ +53 public void setName(String name) { +54 this.name = name; +55 } +56 /** +57 * the url for the reference. +58 */ +59 private String url; +60 +61 /** +62 * Get the value of url. +63 * +64 * @return the value of url +65 */ +66 public String getUrl() { +67 return url; +68 } +69 +70 /** +71 * Set the value of url. +72 * +73 * @param url new value of url +74 */ +75 public void setUrl(String url) { +76 this.url = url; +77 } +78 /** +79 * the source of the reference. +80 */ +81 private String source; +82 +83 /** +84 * Get the value of source. +85 * +86 * @return the value of source +87 */ +88 public String getSource() { +89 return source; +90 } +91 +92 /** +93 * Set the value of source. +94 * +95 * @param source new value of source +96 */ +97 public void setSource(String source) { +98 this.source = source; +99 } +100 +101 @Override +102 public String toString() { +103 return "Reference: { name='" + this.name + "', url='" + this.url + "', source='" + this.source + "' }"; +104 } +105 +106 @Override +107 public boolean equals(Object obj) { +108 if (obj == null) { +109 return false; +110 } +111 if (getClass() != obj.getClass()) { +112 return false; +113 } +114 final Reference other = (Reference) obj; +115 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { 116 return false; 117 } -118 return true; -119 } -120 -121 @Override -122 public int hashCode() { -123 int hash = 5; -124 hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0); -125 hash = 67 * hash + (this.url != null ? this.url.hashCode() : 0); -126 hash = 67 * hash + (this.source != null ? this.source.hashCode() : 0); -127 return hash; -128 } -129 -130 /** -131 * Implementation of the comparable interface. -132 * -133 * @param o the Reference being compared -134 * @return an integer indicating the ordering of the two objects -135 */ -136 @Override -137 public int compareTo(Reference o) { -138 if (source.equals(o.source)) { -139 if (name.equals(o.name)) { -140 if (url.equals(o.url)) { -141 return 0; //they are equal -142 } else { -143 return url.compareTo(o.url); -144 } -145 } else { -146 return name.compareTo(o.name); -147 } -148 } else { -149 return source.compareTo(o.source); -150 } -151 } -152 } +118 if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) { +119 return false; +120 } +121 if ((this.source == null) ? (other.source != null) : !this.source.equals(other.source)) { +122 return false; +123 } +124 return true; +125 } +126 +127 @Override +128 public int hashCode() { +129 int hash = 5; +130 hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0); +131 hash = 67 * hash + (this.url != null ? this.url.hashCode() : 0); +132 hash = 67 * hash + (this.source != null ? this.source.hashCode() : 0); +133 return hash; +134 } +135 +136 /** +137 * Implementation of the comparable interface. +138 * +139 * @param o the Reference being compared +140 * @return an integer indicating the ordering of the two objects +141 */ +142 @Override +143 public int compareTo(Reference o) { +144 if (source.equals(o.source)) { +145 if (name.equals(o.name)) { +146 if (url.equals(o.url)) { +147 return 0; //they are equal +148 } else { +149 return url.compareTo(o.url); +150 } +151 } else { +152 return name.compareTo(o.name); +153 } +154 } else { +155 return source.compareTo(o.source); +156 } +157 } +158 }
      diff --git a/xref/org/owasp/dependencycheck/dependency/Vulnerability.html b/xref/org/owasp/dependencycheck/dependency/Vulnerability.html index 5ea536259..f6382c0f0 100644 --- a/xref/org/owasp/dependencycheck/dependency/Vulnerability.html +++ b/xref/org/owasp/dependencycheck/dependency/Vulnerability.html @@ -29,428 +29,448 @@ 21 import java.util.Set; 22 import java.util.SortedSet; 23 import java.util.TreeSet; -24 -25 /** -26 * Contains the information about a vulnerability. -27 * -28 * @author Jeremy Long -29 */ -30 public class Vulnerability implements Serializable, Comparable<Vulnerability> { -31 -32 /** -33 * The serial version uid. -34 */ -35 private static final long serialVersionUID = 307319490326651052L; -36 /** -37 * The name of the vulnerability. -38 */ -39 private String name; -40 -41 /** -42 * Get the value of name. -43 * -44 * @return the value of name -45 */ -46 public String getName() { -47 return name; -48 } -49 -50 /** -51 * Set the value of name. -52 * -53 * @param name new value of name -54 */ -55 public void setName(String name) { -56 this.name = name; -57 } -58 /** -59 * the description of the vulnerability. -60 */ -61 private String description; -62 -63 /** -64 * Get the value of description. -65 * -66 * @return the value of description -67 */ -68 public String getDescription() { -69 return description; -70 } -71 -72 /** -73 * Set the value of description. -74 * -75 * @param description new value of description -76 */ -77 public void setDescription(String description) { -78 this.description = description; -79 } -80 /** -81 * References for this vulnerability. -82 */ -83 private SortedSet<Reference> references = new TreeSet<Reference>(); -84 -85 /** -86 * Get the value of references. -87 * -88 * @return the value of references -89 */ -90 public Set<Reference> getReferences() { -91 return references; -92 } -93 -94 /** -95 * Set the value of references. -96 * -97 * @param references new value of references -98 */ -99 public void setReferences(SortedSet<Reference> references) { -100 this.references = references; -101 } -102 -103 /** -104 * Adds a reference to the references collection. -105 * -106 * @param ref a reference for the vulnerability -107 */ -108 public void addReference(Reference ref) { -109 this.references.add(ref); -110 } -111 -112 /** -113 * Adds a reference. -114 * -115 * @param referenceSource the source of the reference -116 * @param referenceName the referenceName of the reference -117 * @param referenceUrl the url of the reference -118 */ -119 public void addReference(String referenceSource, String referenceName, String referenceUrl) { -120 final Reference ref = new Reference(); -121 ref.setSource(referenceSource); -122 ref.setName(referenceName); -123 ref.setUrl(referenceUrl); -124 this.references.add(ref); -125 } -126 /** -127 * A set of vulnerable software. -128 */ -129 private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>(); -130 -131 /** -132 * Get the value of vulnerableSoftware. -133 * -134 * @return the value of vulnerableSoftware -135 */ -136 public Set<VulnerableSoftware> getVulnerableSoftware() { -137 return vulnerableSoftware; -138 } -139 -140 /** -141 * Set the value of vulnerableSoftware. -142 * -143 * @param vulnerableSoftware new value of vulnerableSoftware -144 */ -145 public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) { -146 this.vulnerableSoftware = vulnerableSoftware; -147 } -148 -149 /** -150 * Adds an entry for vulnerable software. -151 * -152 * @param cpe string representation of a CPE entry -153 * @return if the add succeeded -154 */ -155 public boolean addVulnerableSoftware(String cpe) { -156 return addVulnerableSoftware(cpe, null); -157 } -158 -159 /** -160 * Adds an entry for vulnerable software. -161 * -162 * @param cpe string representation of a cpe -163 * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable) -164 * @return if the add succeeded -165 */ -166 public boolean addVulnerableSoftware(String cpe, String previousVersion) { -167 final VulnerableSoftware vs = new VulnerableSoftware(); -168 vs.setCpe(cpe); -169 if (previousVersion != null) { -170 vs.setPreviousVersion(previousVersion); -171 } -172 return updateVulnerableSoftware(vs); -173 } -174 -175 /** -176 * Adds or updates a vulnerable software entry. -177 * -178 * @param vulnSoftware the vulnerable software -179 * @return if the update succeeded -180 */ -181 public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) { -182 if (vulnerableSoftware.contains(vulnSoftware)) { -183 vulnerableSoftware.remove(vulnSoftware); -184 } -185 return vulnerableSoftware.add(vulnSoftware); -186 } -187 /** -188 * The CWE for the vulnerability. -189 */ -190 private String cwe; -191 -192 /** -193 * Get the value of cwe. -194 * -195 * @return the value of cwe -196 */ -197 public String getCwe() { -198 return cwe; -199 } -200 -201 /** -202 * Set the value of cwe. -203 * -204 * @param cwe new value of cwe -205 */ -206 public void setCwe(String cwe) { -207 this.cwe = cwe; -208 } -209 /** -210 * CVSS Score. -211 */ -212 private float cvssScore; -213 -214 /** -215 * Get the value of cvssScore. -216 * -217 * @return the value of cvssScore -218 */ -219 public float getCvssScore() { -220 return cvssScore; -221 } -222 -223 /** -224 * Set the value of cvssScore. -225 * -226 * @param cvssScore new value of cvssScore -227 */ -228 public void setCvssScore(float cvssScore) { -229 this.cvssScore = cvssScore; -230 } -231 /** -232 * CVSS Access Vector. -233 */ -234 private String cvssAccessVector; -235 -236 /** -237 * Get the value of cvssAccessVector. -238 * -239 * @return the value of cvssAccessVector -240 */ -241 public String getCvssAccessVector() { -242 return cvssAccessVector; -243 } -244 -245 /** -246 * Set the value of cvssAccessVector. -247 * -248 * @param cvssAccessVector new value of cvssAccessVector -249 */ -250 public void setCvssAccessVector(String cvssAccessVector) { -251 this.cvssAccessVector = cvssAccessVector; -252 } -253 /** -254 * CVSS Access Complexity. -255 */ -256 private String cvssAccessComplexity; -257 -258 /** -259 * Get the value of cvssAccessComplexity. -260 * -261 * @return the value of cvssAccessComplexity -262 */ -263 public String getCvssAccessComplexity() { -264 return cvssAccessComplexity; -265 } -266 -267 /** -268 * Set the value of cvssAccessComplexity. -269 * -270 * @param cvssAccessComplexity new value of cvssAccessComplexity -271 */ -272 public void setCvssAccessComplexity(String cvssAccessComplexity) { -273 this.cvssAccessComplexity = cvssAccessComplexity; -274 } -275 /** -276 * CVSS Authentication. -277 */ -278 private String cvssAuthentication; -279 -280 /** -281 * Get the value of cvssAuthentication. -282 * -283 * @return the value of cvssAuthentication -284 */ -285 public String getCvssAuthentication() { -286 return cvssAuthentication; -287 } -288 -289 /** -290 * Set the value of cvssAuthentication. -291 * -292 * @param cvssAuthentication new value of cvssAuthentication -293 */ -294 public void setCvssAuthentication(String cvssAuthentication) { -295 this.cvssAuthentication = cvssAuthentication; -296 } -297 /** -298 * CVSS Confidentiality Impact. -299 */ -300 private String cvssConfidentialityImpact; -301 -302 /** -303 * Get the value of cvssConfidentialityImpact. -304 * -305 * @return the value of cvssConfidentialityImpact -306 */ -307 public String getCvssConfidentialityImpact() { -308 return cvssConfidentialityImpact; -309 } -310 -311 /** -312 * Set the value of cvssConfidentialityImpact. -313 * -314 * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact -315 */ -316 public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) { -317 this.cvssConfidentialityImpact = cvssConfidentialityImpact; -318 } -319 /** -320 * CVSS Integrity Impact. -321 */ -322 private String cvssIntegrityImpact; -323 -324 /** -325 * Get the value of cvssIntegrityImpact. -326 * -327 * @return the value of cvssIntegrityImpact -328 */ -329 public String getCvssIntegrityImpact() { -330 return cvssIntegrityImpact; -331 } -332 -333 /** -334 * Set the value of cvssIntegrityImpact. -335 * -336 * @param cvssIntegrityImpact new value of cvssIntegrityImpact -337 */ -338 public void setCvssIntegrityImpact(String cvssIntegrityImpact) { -339 this.cvssIntegrityImpact = cvssIntegrityImpact; -340 } -341 /** -342 * CVSS Availability Impact. -343 */ -344 private String cvssAvailabilityImpact; -345 -346 /** -347 * Get the value of cvssAvailabilityImpact. -348 * -349 * @return the value of cvssAvailabilityImpact -350 */ -351 public String getCvssAvailabilityImpact() { -352 return cvssAvailabilityImpact; -353 } -354 -355 /** -356 * Set the value of cvssAvailabilityImpact. -357 * -358 * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact -359 */ -360 public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) { -361 this.cvssAvailabilityImpact = cvssAvailabilityImpact; -362 } -363 -364 @Override -365 public boolean equals(Object obj) { -366 if (obj == null) { -367 return false; -368 } -369 if (getClass() != obj.getClass()) { -370 return false; -371 } -372 final Vulnerability other = (Vulnerability) obj; -373 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { -374 return false; -375 } -376 return true; -377 } -378 -379 @Override -380 public int hashCode() { -381 int hash = 5; -382 hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0); -383 return hash; -384 } -385 -386 /** -387 * Compares two vulnerabilities. -388 * -389 * @param v a vulnerability to be compared -390 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than -391 * the specified vulnerability -392 */ -393 @Override -394 public int compareTo(Vulnerability v) { -395 return v.getName().compareTo(this.getName()); -396 } -397 -398 /** -399 * The CPE id that caused this vulnerability to be flagged. -400 */ -401 private String matchedCPE; -402 /** -403 * Whether or not all previous versions were affected. -404 */ -405 private String matchedAllPreviousCPE; -406 -407 /** -408 * Sets the CPE that caused this vulnerability to be flagged. -409 * -410 * @param cpeId a CPE identifier -411 * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is -412 * considered true) -413 */ -414 public void setMatchedCPE(String cpeId, String previous) { -415 matchedCPE = cpeId; -416 matchedAllPreviousCPE = previous; -417 } -418 -419 /** -420 * Get the value of matchedCPE. -421 * -422 * @return the value of matchedCPE -423 */ -424 public String getMatchedCPE() { -425 return matchedCPE; -426 } -427 -428 /** -429 * Get the value of matchedAllPreviousCPE. -430 * -431 * @return the value of matchedAllPreviousCPE -432 */ -433 public String getMatchedAllPreviousCPE() { -434 return matchedAllPreviousCPE; -435 } -436 -437 /** -438 * Determines whether or not matchedAllPreviousCPE has been set. -439 * -440 * @return true if matchedAllPreviousCPE is not null; otherwise false -441 */ -442 public boolean hasMatchedAllPreviousCPE() { -443 return matchedAllPreviousCPE != null; -444 } -445 } +24 import java.util.Iterator; +25 +26 /** +27 * Contains the information about a vulnerability. +28 * +29 * @author Jeremy Long +30 */ +31 public class Vulnerability implements Serializable, Comparable<Vulnerability> { +32 +33 /** +34 * The serial version uid. +35 */ +36 private static final long serialVersionUID = 307319490326651052L; +37 +38 /** +39 * The name of the vulnerability. +40 */ +41 private String name; +42 +43 /** +44 * Get the value of name. +45 * +46 * @return the value of name +47 */ +48 public String getName() { +49 return name; +50 } +51 +52 /** +53 * Set the value of name. +54 * +55 * @param name new value of name +56 */ +57 public void setName(String name) { +58 this.name = name; +59 } +60 /** +61 * the description of the vulnerability. +62 */ +63 private String description; +64 +65 /** +66 * Get the value of description. +67 * +68 * @return the value of description +69 */ +70 public String getDescription() { +71 return description; +72 } +73 +74 /** +75 * Set the value of description. +76 * +77 * @param description new value of description +78 */ +79 public void setDescription(String description) { +80 this.description = description; +81 } +82 /** +83 * References for this vulnerability. +84 */ +85 private SortedSet<Reference> references = new TreeSet<Reference>(); +86 +87 /** +88 * Get the value of references. +89 * +90 * @return the value of references +91 */ +92 public Set<Reference> getReferences() { +93 return references; +94 } +95 +96 /** +97 * Set the value of references. +98 * +99 * @param references new value of references +100 */ +101 public void setReferences(SortedSet<Reference> references) { +102 this.references = references; +103 } +104 +105 /** +106 * Adds a reference to the references collection. +107 * +108 * @param ref a reference for the vulnerability +109 */ +110 public void addReference(Reference ref) { +111 this.references.add(ref); +112 } +113 +114 /** +115 * Adds a reference. +116 * +117 * @param referenceSource the source of the reference +118 * @param referenceName the referenceName of the reference +119 * @param referenceUrl the url of the reference +120 */ +121 public void addReference(String referenceSource, String referenceName, String referenceUrl) { +122 final Reference ref = new Reference(); +123 ref.setSource(referenceSource); +124 ref.setName(referenceName); +125 ref.setUrl(referenceUrl); +126 this.references.add(ref); +127 } +128 /** +129 * A set of vulnerable software. +130 */ +131 private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>(); +132 +133 /** +134 * Get the value of vulnerableSoftware. +135 * +136 * @return the value of vulnerableSoftware +137 */ +138 public Set<VulnerableSoftware> getVulnerableSoftware() { +139 return vulnerableSoftware; +140 } +141 +142 /** +143 * Set the value of vulnerableSoftware. +144 * +145 * @param vulnerableSoftware new value of vulnerableSoftware +146 */ +147 public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) { +148 this.vulnerableSoftware = vulnerableSoftware; +149 } +150 +151 /** +152 * Adds an entry for vulnerable software. +153 * +154 * @param cpe string representation of a CPE entry +155 * @return if the add succeeded +156 */ +157 public boolean addVulnerableSoftware(String cpe) { +158 return addVulnerableSoftware(cpe, null); +159 } +160 +161 /** +162 * Adds an entry for vulnerable software. +163 * +164 * @param cpe string representation of a cpe +165 * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable) +166 * @return if the add succeeded +167 */ +168 public boolean addVulnerableSoftware(String cpe, String previousVersion) { +169 final VulnerableSoftware vs = new VulnerableSoftware(); +170 vs.setCpe(cpe); +171 if (previousVersion != null) { +172 vs.setPreviousVersion(previousVersion); +173 } +174 return updateVulnerableSoftware(vs); +175 } +176 +177 /** +178 * Adds or updates a vulnerable software entry. +179 * +180 * @param vulnSoftware the vulnerable software +181 * @return if the update succeeded +182 */ +183 public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) { +184 if (vulnerableSoftware.contains(vulnSoftware)) { +185 vulnerableSoftware.remove(vulnSoftware); +186 } +187 return vulnerableSoftware.add(vulnSoftware); +188 } +189 /** +190 * The CWE for the vulnerability. +191 */ +192 private String cwe; +193 +194 /** +195 * Get the value of cwe. +196 * +197 * @return the value of cwe +198 */ +199 public String getCwe() { +200 return cwe; +201 } +202 +203 /** +204 * Set the value of cwe. +205 * +206 * @param cwe new value of cwe +207 */ +208 public void setCwe(String cwe) { +209 this.cwe = cwe; +210 } +211 /** +212 * CVSS Score. +213 */ +214 private float cvssScore; +215 +216 /** +217 * Get the value of cvssScore. +218 * +219 * @return the value of cvssScore +220 */ +221 public float getCvssScore() { +222 return cvssScore; +223 } +224 +225 /** +226 * Set the value of cvssScore. +227 * +228 * @param cvssScore new value of cvssScore +229 */ +230 public void setCvssScore(float cvssScore) { +231 this.cvssScore = cvssScore; +232 } +233 /** +234 * CVSS Access Vector. +235 */ +236 private String cvssAccessVector; +237 +238 /** +239 * Get the value of cvssAccessVector. +240 * +241 * @return the value of cvssAccessVector +242 */ +243 public String getCvssAccessVector() { +244 return cvssAccessVector; +245 } +246 +247 /** +248 * Set the value of cvssAccessVector. +249 * +250 * @param cvssAccessVector new value of cvssAccessVector +251 */ +252 public void setCvssAccessVector(String cvssAccessVector) { +253 this.cvssAccessVector = cvssAccessVector; +254 } +255 /** +256 * CVSS Access Complexity. +257 */ +258 private String cvssAccessComplexity; +259 +260 /** +261 * Get the value of cvssAccessComplexity. +262 * +263 * @return the value of cvssAccessComplexity +264 */ +265 public String getCvssAccessComplexity() { +266 return cvssAccessComplexity; +267 } +268 +269 /** +270 * Set the value of cvssAccessComplexity. +271 * +272 * @param cvssAccessComplexity new value of cvssAccessComplexity +273 */ +274 public void setCvssAccessComplexity(String cvssAccessComplexity) { +275 this.cvssAccessComplexity = cvssAccessComplexity; +276 } +277 /** +278 * CVSS Authentication. +279 */ +280 private String cvssAuthentication; +281 +282 /** +283 * Get the value of cvssAuthentication. +284 * +285 * @return the value of cvssAuthentication +286 */ +287 public String getCvssAuthentication() { +288 return cvssAuthentication; +289 } +290 +291 /** +292 * Set the value of cvssAuthentication. +293 * +294 * @param cvssAuthentication new value of cvssAuthentication +295 */ +296 public void setCvssAuthentication(String cvssAuthentication) { +297 this.cvssAuthentication = cvssAuthentication; +298 } +299 /** +300 * CVSS Confidentiality Impact. +301 */ +302 private String cvssConfidentialityImpact; +303 +304 /** +305 * Get the value of cvssConfidentialityImpact. +306 * +307 * @return the value of cvssConfidentialityImpact +308 */ +309 public String getCvssConfidentialityImpact() { +310 return cvssConfidentialityImpact; +311 } +312 +313 /** +314 * Set the value of cvssConfidentialityImpact. +315 * +316 * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact +317 */ +318 public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) { +319 this.cvssConfidentialityImpact = cvssConfidentialityImpact; +320 } +321 /** +322 * CVSS Integrity Impact. +323 */ +324 private String cvssIntegrityImpact; +325 +326 /** +327 * Get the value of cvssIntegrityImpact. +328 * +329 * @return the value of cvssIntegrityImpact +330 */ +331 public String getCvssIntegrityImpact() { +332 return cvssIntegrityImpact; +333 } +334 +335 /** +336 * Set the value of cvssIntegrityImpact. +337 * +338 * @param cvssIntegrityImpact new value of cvssIntegrityImpact +339 */ +340 public void setCvssIntegrityImpact(String cvssIntegrityImpact) { +341 this.cvssIntegrityImpact = cvssIntegrityImpact; +342 } +343 /** +344 * CVSS Availability Impact. +345 */ +346 private String cvssAvailabilityImpact; +347 +348 /** +349 * Get the value of cvssAvailabilityImpact. +350 * +351 * @return the value of cvssAvailabilityImpact +352 */ +353 public String getCvssAvailabilityImpact() { +354 return cvssAvailabilityImpact; +355 } +356 +357 /** +358 * Set the value of cvssAvailabilityImpact. +359 * +360 * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact +361 */ +362 public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) { +363 this.cvssAvailabilityImpact = cvssAvailabilityImpact; +364 } +365 +366 @Override +367 public boolean equals(Object obj) { +368 if (obj == null) { +369 return false; +370 } +371 if (getClass() != obj.getClass()) { +372 return false; +373 } +374 final Vulnerability other = (Vulnerability) obj; +375 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { +376 return false; +377 } +378 return true; +379 } +380 +381 @Override +382 public int hashCode() { +383 int hash = 5; +384 hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0); +385 return hash; +386 } +387 +388 @Override +389 public String toString() { +390 final StringBuilder sb = new StringBuilder("Vulnerability "); +391 sb.append(this.name); +392 sb.append("\nReferences:\n"); +393 for (Iterator i = this.references.iterator(); i.hasNext();) { +394 sb.append("=> "); +395 sb.append(i.next()); +396 sb.append("\n"); +397 } +398 sb.append("\nSoftware:\n"); +399 for (Iterator i = this.vulnerableSoftware.iterator(); i.hasNext();) { +400 sb.append("=> "); +401 sb.append(i.next()); +402 sb.append("\n"); +403 } +404 return sb.toString(); +405 } +406 /** +407 * Compares two vulnerabilities. +408 * +409 * @param v a vulnerability to be compared +410 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than +411 * the specified vulnerability +412 */ +413 @Override +414 public int compareTo(Vulnerability v) { +415 return v.getName().compareTo(this.getName()); +416 } +417 +418 /** +419 * The CPE id that caused this vulnerability to be flagged. +420 */ +421 private String matchedCPE; +422 /** +423 * Whether or not all previous versions were affected. +424 */ +425 private String matchedAllPreviousCPE; +426 +427 /** +428 * Sets the CPE that caused this vulnerability to be flagged. +429 * +430 * @param cpeId a CPE identifier +431 * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is +432 * considered true) +433 */ +434 public void setMatchedCPE(String cpeId, String previous) { +435 matchedCPE = cpeId; +436 matchedAllPreviousCPE = previous; +437 } +438 +439 /** +440 * Get the value of matchedCPE. +441 * +442 * @return the value of matchedCPE +443 */ +444 public String getMatchedCPE() { +445 return matchedCPE; +446 } +447 +448 /** +449 * Get the value of matchedAllPreviousCPE. +450 * +451 * @return the value of matchedAllPreviousCPE +452 */ +453 public String getMatchedAllPreviousCPE() { +454 return matchedAllPreviousCPE; +455 } +456 +457 /** +458 * Determines whether or not matchedAllPreviousCPE has been set. +459 * +460 * @return true if matchedAllPreviousCPE is not null; otherwise false +461 */ +462 public boolean hasMatchedAllPreviousCPE() { +463 return matchedAllPreviousCPE != null; +464 } +465 }
      diff --git a/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html b/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html index d65afcba3..70070a957 100644 --- a/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html +++ b/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html @@ -146,7 +146,7 @@ 138 return false; 139 } 140 final VulnerableSoftware other = (VulnerableSoftware) obj; -141 if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) { +141 if ((this.name == null) ? (other.getName() != null) : !this.name.equals(other.getName())) { 142 return false; 143 } 144 return true; @@ -160,7 +160,7 @@ 152 @Override 153 public int hashCode() { 154 int hash = 7; -155 hash = 83 * hash + (this.getName() != null ? this.getName().hashCode() : 0); +155 hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0); 156 return hash; 157 } 158 @@ -171,7 +171,7 @@ 163 */ 164 @Override 165 public String toString() { -166 return "VulnerableSoftware{ name=" + name + ", previousVersion=" + previousVersion + '}'; +166 return "VulnerableSoftware{" + name + "[" + previousVersion + "]}"; 167 } 168 169 /** @@ -183,203 +183,194 @@ 175 @Override 176 public int compareTo(VulnerableSoftware vs) { 177 int result = 0; -178 final String[] left = this.getName().split(":"); +178 final String[] left = this.name.split(":"); 179 final String[] right = vs.getName().split(":"); 180 final int max = (left.length <= right.length) ? left.length : right.length; 181 if (max > 0) { 182 for (int i = 0; result == 0 && i < max; i++) { -183 final String[] subLeft = left[i].split("\\."); -184 final String[] subRight = right[i].split("\\."); +183 final String[] subLeft = left[i].split("(\\.|-)"); +184 final String[] subRight = right[i].split("(\\.|-)"); 185 final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length; 186 if (subMax > 0) { 187 for (int x = 0; result == 0 && x < subMax; x++) { 188 if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) { 189 try { 190 result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x])); -191 // final long iLeft = Long.parseLong(subLeft[x]); -192 // final long iRight = Long.parseLong(subRight[x]); -193 // if (iLeft != iRight) { -194 // if (iLeft > iRight) { -195 // result = 2; -196 // } else { -197 // result = -2; -198 // } -199 // } -200 } catch (NumberFormatException ex) { -201 //ignore the exception - they obviously aren't numbers -202 if (!subLeft[x].equalsIgnoreCase(subRight[x])) { -203 result = subLeft[x].compareToIgnoreCase(subRight[x]); -204 } -205 } -206 } else { -207 result = subLeft[x].compareToIgnoreCase(subRight[x]); -208 } -209 } -210 if (result == 0) { -211 if (subLeft.length > subRight.length) { -212 result = 2; -213 } -214 if (subRight.length > subLeft.length) { -215 result = -2; -216 } -217 } -218 } else { -219 result = left[i].compareToIgnoreCase(right[i]); -220 } -221 } -222 if (result == 0) { -223 if (left.length > right.length) { -224 result = 2; -225 } -226 if (right.length > left.length) { -227 result = -2; -228 } -229 } -230 } else { -231 result = this.getName().compareToIgnoreCase(vs.getName()); -232 } -233 return result; -234 } -235 -236 /** -237 * Determines if the string passed in is a positive integer. -238 * -239 * @param str the string to test -240 * @return true if the string only contains 0-9, otherwise false. -241 */ -242 private static boolean isPositiveInteger(final String str) { -243 if (str == null || str.isEmpty()) { -244 return false; -245 } -246 for (int i = 0; i < str.length(); i++) { -247 final char c = str.charAt(i); -248 if (c < '0' || c > '9') { -249 return false; -250 } -251 } -252 return true; -253 } -254 /** -255 * The name of the cpe. -256 */ -257 private String name; +191 } catch (NumberFormatException ex) { +192 //ignore the exception - they obviously aren't numbers +193 if (!subLeft[x].equalsIgnoreCase(subRight[x])) { +194 result = subLeft[x].compareToIgnoreCase(subRight[x]); +195 } +196 } +197 } else { +198 result = subLeft[x].compareToIgnoreCase(subRight[x]); +199 } +200 } +201 if (result == 0) { +202 if (subLeft.length > subRight.length) { +203 result = 2; +204 } +205 if (subRight.length > subLeft.length) { +206 result = -2; +207 } +208 } +209 } else { +210 result = left[i].compareToIgnoreCase(right[i]); +211 } +212 } +213 if (result == 0) { +214 if (left.length > right.length) { +215 result = 2; +216 } +217 if (right.length > left.length) { +218 result = -2; +219 } +220 } +221 } else { +222 result = this.getName().compareToIgnoreCase(vs.getName()); +223 } +224 return result; +225 } +226 +227 /** +228 * Determines if the string passed in is a positive integer. +229 * +230 * @param str the string to test +231 * @return true if the string only contains 0-9, otherwise false. +232 */ +233 private static boolean isPositiveInteger(final String str) { +234 if (str == null || str.isEmpty()) { +235 return false; +236 } +237 for (int i = 0; i < str.length(); i++) { +238 final char c = str.charAt(i); +239 if (c < '0' || c > '9') { +240 return false; +241 } +242 } +243 return true; +244 } +245 /** +246 * The name of the cpe. +247 */ +248 private String name; +249 +250 /** +251 * Get the value of name. +252 * +253 * @return the value of name +254 */ +255 public String getName() { +256 return name; +257 } 258 259 /** -260 * Get the value of name. +260 * Set the value of name. 261 * -262 * @return the value of name +262 * @param name new value of name 263 */ -264 public String getName() { -265 return name; +264 public void setName(String name) { +265 this.name = name; 266 } -267 -268 /** -269 * Set the value of name. -270 * -271 * @param name new value of name -272 */ -273 public void setName(String name) { -274 this.name = name; -275 } -276 /** -277 * The product version number. -278 */ -279 private String version; +267 /** +268 * The product version number. +269 */ +270 private String version; +271 +272 /** +273 * Get the value of version. +274 * +275 * @return the value of version +276 */ +277 public String getVersion() { +278 return version; +279 } 280 281 /** -282 * Get the value of version. +282 * Set the value of version. 283 * -284 * @return the value of version +284 * @param version new value of version 285 */ -286 public String getVersion() { -287 return version; +286 public void setVersion(String version) { +287 this.version = version; 288 } -289 -290 /** -291 * Set the value of version. -292 * -293 * @param version new value of version -294 */ -295 public void setVersion(String version) { -296 this.version = version; -297 } -298 /** -299 * The product update version. -300 */ -301 private String update; +289 /** +290 * The product update version. +291 */ +292 private String update; +293 +294 /** +295 * Get the value of update. +296 * +297 * @return the value of update +298 */ +299 public String getUpdate() { +300 return update; +301 } 302 303 /** -304 * Get the value of update. +304 * Set the value of update. 305 * -306 * @return the value of update +306 * @param update new value of update 307 */ -308 public String getUpdate() { -309 return update; +308 public void setUpdate(String update) { +309 this.update = update; 310 } -311 -312 /** -313 * Set the value of update. -314 * -315 * @param update new value of update -316 */ -317 public void setUpdate(String update) { -318 this.update = update; -319 } -320 /** -321 * The product edition. -322 */ -323 private String edition; +311 /** +312 * The product edition. +313 */ +314 private String edition; +315 +316 /** +317 * Get the value of edition. +318 * +319 * @return the value of edition +320 */ +321 public String getEdition() { +322 return edition; +323 } 324 325 /** -326 * Get the value of edition. +326 * Set the value of edition. 327 * -328 * @return the value of edition +328 * @param edition new value of edition 329 */ -330 public String getEdition() { -331 return edition; +330 public void setEdition(String edition) { +331 this.edition = edition; 332 } 333 334 /** -335 * Set the value of edition. +335 * Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default. 336 * -337 * @param edition new value of edition -338 */ -339 public void setEdition(String edition) { -340 this.edition = edition; -341 } -342 -343 /** -344 * Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default. -345 * -346 * @param string the string to URL Decode -347 * @return the URL Decoded string -348 */ -349 private String urlDecode(String string) { -350 final String text = string.replace("+", "%2B"); -351 String result; -352 try { -353 result = URLDecoder.decode(text, "UTF-8"); -354 } catch (UnsupportedEncodingException ex) { -355 try { -356 result = URLDecoder.decode(text, "ASCII"); -357 } catch (UnsupportedEncodingException ex1) { -358 result = defaultUrlDecode(text); -359 } -360 } -361 return result; -362 } -363 -364 /** -365 * Call {@link java.net.URLDecoder#decode(String)} to URL decode using the default encoding. -366 * -367 * @param text www-form-encoded URL to decode -368 * @return the newly decoded String -369 */ -370 @SuppressWarnings("deprecation") -371 private String defaultUrlDecode(final String text) { -372 return URLDecoder.decode(text); -373 } -374 } +337 * @param string the string to URL Decode +338 * @return the URL Decoded string +339 */ +340 private String urlDecode(String string) { +341 final String text = string.replace("+", "%2B"); +342 String result; +343 try { +344 result = URLDecoder.decode(text, "UTF-8"); +345 } catch (UnsupportedEncodingException ex) { +346 try { +347 result = URLDecoder.decode(text, "ASCII"); +348 } catch (UnsupportedEncodingException ex1) { +349 result = defaultUrlDecode(text); +350 } +351 } +352 return result; +353 } +354 +355 /** +356 * Call {@link java.net.URLDecoder#decode(String)} to URL decode using the default encoding. +357 * +358 * @param text www-form-encoded URL to decode +359 * @return the newly decoded String +360 */ +361 @SuppressWarnings("deprecation") +362 private String defaultUrlDecode(final String text) { +363 return URLDecoder.decode(text); +364 } +365 }
      diff --git a/xref/org/owasp/dependencycheck/dependency/package-frame.html b/xref/org/owasp/dependencycheck/dependency/package-frame.html index 7dd40873a..44d09bf00 100644 --- a/xref/org/owasp/dependencycheck/dependency/package-frame.html +++ b/xref/org/owasp/dependencycheck/dependency/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.dependency diff --git a/xref/org/owasp/dependencycheck/dependency/package-summary.html b/xref/org/owasp/dependencycheck/dependency/package-summary.html index 5cebcd1c2..170bd9d72 100644 --- a/xref/org/owasp/dependencycheck/dependency/package-summary.html +++ b/xref/org/owasp/dependencycheck/dependency/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.dependency diff --git a/xref/org/owasp/dependencycheck/exception/package-frame.html b/xref/org/owasp/dependencycheck/exception/package-frame.html index 24b0e17a2..8bea63e53 100644 --- a/xref/org/owasp/dependencycheck/exception/package-frame.html +++ b/xref/org/owasp/dependencycheck/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.exception + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.exception diff --git a/xref/org/owasp/dependencycheck/exception/package-summary.html b/xref/org/owasp/dependencycheck/exception/package-summary.html index 83ff5ea0a..de92a70da 100644 --- a/xref/org/owasp/dependencycheck/exception/package-summary.html +++ b/xref/org/owasp/dependencycheck/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.exception + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.exception diff --git a/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html b/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html index 2d3f0e1f0..31f6bcfa6 100644 --- a/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html +++ b/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html @@ -102,1005 +102,1040 @@ 94 @Parameter(defaultValue = "${project.build.directory}", required = true) 95 private File outputDirectory; 96 /** -97 * Specifies the destination directory for the generated Dependency-Check report. This generally maps to "target/site". -98 */ -99 @Parameter(property = "project.reporting.outputDirectory", required = true) -100 private File reportOutputDirectory; -101 /** -102 * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which -103 * means since the CVSS scores are 0-10, by default the build will never fail. -104 */ -105 @SuppressWarnings("CanBeFinal") -106 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true) -107 private float failBuildOnCVSS = 11; -108 /** -109 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default -110 * is true. -111 */ -112 @SuppressWarnings("CanBeFinal") -113 @Parameter(property = "autoUpdate") -114 private Boolean autoUpdate; -115 /** -116 * Generate aggregate reports in multi-module projects. -117 * -118 * @deprecated use the aggregate goal instead +97 * Specifies the destination directory for the generated Dependency-Check +98 * report. This generally maps to "target/site". +99 */ +100 @Parameter(property = "project.reporting.outputDirectory", required = true) +101 private File reportOutputDirectory; +102 /** +103 * Specifies if the build should be failed if a CVSS score above a specified +104 * level is identified. The default is 11 which means since the CVSS scores +105 * are 0-10, by default the build will never fail. +106 */ +107 @SuppressWarnings("CanBeFinal") +108 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true) +109 private float failBuildOnCVSS = 11; +110 /** +111 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +112 * recommended that this be turned to false. Default is true. +113 */ +114 @SuppressWarnings("CanBeFinal") +115 @Parameter(property = "autoUpdate") +116 private Boolean autoUpdate; +117 /** +118 * Sets whether Experimental analyzers are enabled. Default is false. 119 */ -120 @Parameter(property = "aggregate") -121 @Deprecated -122 private Boolean aggregate; +120 @SuppressWarnings("CanBeFinal") +121 @Parameter(property = "enableExperimental") +122 private Boolean enableExperimental; 123 /** -124 * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the -125 * Site plug-in unless the externalReport is set to true. Default is HTML. -126 */ -127 @SuppressWarnings("CanBeFinal") -128 @Parameter(property = "format", defaultValue = "HTML", required = true) -129 private String format = "HTML"; -130 /** -131 * The Maven settings. -132 */ -133 @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false) -134 private org.apache.maven.settings.Settings mavenSettings; -135 -136 /** -137 * The maven settings proxy id. -138 */ -139 @SuppressWarnings("CanBeFinal") -140 @Parameter(property = "mavenSettingsProxyId", required = false) -141 private String mavenSettingsProxyId; -142 -143 /** -144 * The Connection Timeout. -145 */ -146 @Parameter(property = "connectionTimeout", defaultValue = "", required = false) -147 private String connectionTimeout; -148 /** -149 * The path to the suppression file. -150 */ -151 @Parameter(property = "suppressionFile", defaultValue = "", required = false) -152 private String suppressionFile; -153 /** -154 * Flag indicating whether or not to show a summary in the output. -155 */ -156 @Parameter(property = "showSummary", defaultValue = "true", required = false) -157 private boolean showSummary = true; -158 -159 /** -160 * Whether or not the Jar Analyzer is enabled. -161 */ -162 @Parameter(property = "jarAnalyzerEnabled", required = false) -163 private Boolean jarAnalyzerEnabled; -164 -165 /** -166 * Whether or not the Archive Analyzer is enabled. -167 */ -168 @Parameter(property = "archiveAnalyzerEnabled", required = false) -169 private Boolean archiveAnalyzerEnabled; -170 -171 /** -172 * Sets whether the Python Distribution Analyzer will be used. -173 */ -174 @Parameter(property = "pyDistributionAnalyzerEnabled", required = false) -175 private Boolean pyDistributionAnalyzerEnabled; -176 /** -177 * Sets whether the Python Package Analyzer will be used. -178 */ -179 @Parameter(property = "pyPackageAnalyzerEnabled", required = false) -180 private Boolean pyPackageAnalyzerEnabled; -181 /** -182 * Sets whether the Ruby Gemspec Analyzer will be used. -183 */ -184 @Parameter(property = "rubygemsAnalyzerEnabled", required = false) -185 private Boolean rubygemsAnalyzerEnabled; -186 /** -187 * Sets whether or not the openssl Analyzer should be used. -188 */ -189 @Parameter(property = "opensslAnalyzerEnabled", required = false) -190 private Boolean opensslAnalyzerEnabled; -191 /** -192 * Sets whether or not the CMake Analyzer should be used. -193 */ -194 @Parameter(property = "cmakeAnalyzerEnabled", required = false) -195 private Boolean cmakeAnalyzerEnabled; -196 /** -197 * Sets whether or not the autoconf Analyzer should be used. -198 */ -199 @Parameter(property = "autoconfAnalyzerEnabled", required = false) -200 private Boolean autoconfAnalyzerEnabled; -201 /** -202 * Sets whether or not the PHP Composer Lock File Analyzer should be used. -203 */ -204 @Parameter(property = "composerAnalyzerEnabled", required = false) -205 private Boolean composerAnalyzerEnabled; -206 /** -207 * Sets whether or not the Node.js Analyzer should be used. -208 */ -209 @Parameter(property = "nodeAnalyzerEnabled", required = false) -210 private Boolean nodeAnalyzerEnabled; -211 -212 /** -213 * Whether or not the .NET Assembly Analyzer is enabled. -214 */ -215 @Parameter(property = "assemblyAnalyzerEnabled", required = false) -216 private Boolean assemblyAnalyzerEnabled; -217 -218 /** -219 * Whether or not the .NET Nuspec Analyzer is enabled. -220 */ -221 @Parameter(property = "nuspecAnalyzerEnabled", required = false) -222 private Boolean nuspecAnalyzerEnabled; -223 -224 /** -225 * Whether or not the Central Analyzer is enabled. -226 */ -227 @Parameter(property = "centralAnalyzerEnabled", required = false) -228 private Boolean centralAnalyzerEnabled; -229 -230 /** -231 * Whether or not the Nexus Analyzer is enabled. -232 */ -233 @Parameter(property = "nexusAnalyzerEnabled", required = false) -234 private Boolean nexusAnalyzerEnabled; -235 -236 /** -237 * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local). -238 */ -239 @Parameter(property = "nexusUrl", required = false) -240 private String nexusUrl; -241 /** -242 * Whether or not the configured proxy is used to connect to Nexus. -243 */ -244 @Parameter(property = "nexusUsesProxy", required = false) -245 private Boolean nexusUsesProxy; -246 /** -247 * The database connection string. +124 * Generate aggregate reports in multi-module projects. +125 * +126 * @deprecated use the aggregate goal instead +127 */ +128 @Parameter(property = "aggregate") +129 @Deprecated +130 private Boolean aggregate; +131 /** +132 * The report format to be generated (HTML, XML, VULN, ALL). This +133 * configuration option has no affect if using this within the Site plug-in +134 * unless the externalReport is set to true. Default is HTML. +135 */ +136 @SuppressWarnings("CanBeFinal") +137 @Parameter(property = "format", defaultValue = "HTML", required = true) +138 private String format = "HTML"; +139 /** +140 * The Maven settings. +141 */ +142 @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false) +143 private org.apache.maven.settings.Settings mavenSettings; +144 +145 /** +146 * The maven settings proxy id. +147 */ +148 @SuppressWarnings("CanBeFinal") +149 @Parameter(property = "mavenSettingsProxyId", required = false) +150 private String mavenSettingsProxyId; +151 +152 /** +153 * The Connection Timeout. +154 */ +155 @Parameter(property = "connectionTimeout", defaultValue = "", required = false) +156 private String connectionTimeout; +157 /** +158 * The path to the suppression file. +159 */ +160 @Parameter(property = "suppressionFile", defaultValue = "", required = false) +161 private String suppressionFile; +162 /** +163 * Flag indicating whether or not to show a summary in the output. +164 */ +165 @Parameter(property = "showSummary", defaultValue = "true", required = false) +166 private boolean showSummary = true; +167 +168 /** +169 * Whether or not the Jar Analyzer is enabled. +170 */ +171 @Parameter(property = "jarAnalyzerEnabled", required = false) +172 private Boolean jarAnalyzerEnabled; +173 +174 /** +175 * Whether or not the Archive Analyzer is enabled. +176 */ +177 @Parameter(property = "archiveAnalyzerEnabled", required = false) +178 private Boolean archiveAnalyzerEnabled; +179 +180 /** +181 * Sets whether the Python Distribution Analyzer will be used. +182 */ +183 @Parameter(property = "pyDistributionAnalyzerEnabled", required = false) +184 private Boolean pyDistributionAnalyzerEnabled; +185 /** +186 * Sets whether the Python Package Analyzer will be used. +187 */ +188 @Parameter(property = "pyPackageAnalyzerEnabled", required = false) +189 private Boolean pyPackageAnalyzerEnabled; +190 /** +191 * Sets whether the Ruby Gemspec Analyzer will be used. +192 */ +193 @Parameter(property = "rubygemsAnalyzerEnabled", required = false) +194 private Boolean rubygemsAnalyzerEnabled; +195 /** +196 * Sets whether or not the openssl Analyzer should be used. +197 */ +198 @Parameter(property = "opensslAnalyzerEnabled", required = false) +199 private Boolean opensslAnalyzerEnabled; +200 /** +201 * Sets whether or not the CMake Analyzer should be used. +202 */ +203 @Parameter(property = "cmakeAnalyzerEnabled", required = false) +204 private Boolean cmakeAnalyzerEnabled; +205 /** +206 * Sets whether or not the autoconf Analyzer should be used. +207 */ +208 @Parameter(property = "autoconfAnalyzerEnabled", required = false) +209 private Boolean autoconfAnalyzerEnabled; +210 /** +211 * Sets whether or not the PHP Composer Lock File Analyzer should be used. +212 */ +213 @Parameter(property = "composerAnalyzerEnabled", required = false) +214 private Boolean composerAnalyzerEnabled; +215 /** +216 * Sets whether or not the Node.js Analyzer should be used. +217 */ +218 @Parameter(property = "nodeAnalyzerEnabled", required = false) +219 private Boolean nodeAnalyzerEnabled; +220 +221 /** +222 * Whether or not the .NET Assembly Analyzer is enabled. +223 */ +224 @Parameter(property = "assemblyAnalyzerEnabled", required = false) +225 private Boolean assemblyAnalyzerEnabled; +226 +227 /** +228 * Whether or not the .NET Nuspec Analyzer is enabled. +229 */ +230 @Parameter(property = "nuspecAnalyzerEnabled", required = false) +231 private Boolean nuspecAnalyzerEnabled; +232 +233 /** +234 * Whether or not the Central Analyzer is enabled. +235 */ +236 @Parameter(property = "centralAnalyzerEnabled", required = false) +237 private Boolean centralAnalyzerEnabled; +238 +239 /** +240 * Whether or not the Nexus Analyzer is enabled. +241 */ +242 @Parameter(property = "nexusAnalyzerEnabled", required = false) +243 private Boolean nexusAnalyzerEnabled; +244 +245 /** +246 * The URL of a Nexus server's REST API end point +247 * (http://domain/nexus/service/local). 248 */ -249 @Parameter(property = "connectionString", defaultValue = "", required = false) -250 private String connectionString; -251 -252 /** -253 * Returns the connection string. -254 * -255 * @return the connection string -256 */ -257 protected String getConnectionString() { -258 return connectionString; -259 } -260 /** -261 * The database driver name. An example would be org.h2.Driver. -262 */ -263 @Parameter(property = "databaseDriverName", defaultValue = "", required = false) -264 private String databaseDriverName; -265 /** -266 * The path to the database driver if it is not on the class path. -267 */ -268 @Parameter(property = "databaseDriverPath", defaultValue = "", required = false) -269 private String databaseDriverPath; +249 @Parameter(property = "nexusUrl", required = false) +250 private String nexusUrl; +251 /** +252 * Whether or not the configured proxy is used to connect to Nexus. +253 */ +254 @Parameter(property = "nexusUsesProxy", required = false) +255 private Boolean nexusUsesProxy; +256 /** +257 * The database connection string. +258 */ +259 @Parameter(property = "connectionString", defaultValue = "", required = false) +260 private String connectionString; +261 +262 /** +263 * Returns the connection string. +264 * +265 * @return the connection string +266 */ +267 protected String getConnectionString() { +268 return connectionString; +269 } 270 /** -271 * The server id in the settings.xml; used to retrieve encrypted passwords from the settings.xml. +271 * The database driver name. An example would be org.h2.Driver. 272 */ -273 @Parameter(property = "serverId", defaultValue = "", required = false) -274 private String serverId; +273 @Parameter(property = "databaseDriverName", defaultValue = "", required = false) +274 private String databaseDriverName; 275 /** -276 * A reference to the settings.xml settings. +276 * The path to the database driver if it is not on the class path. 277 */ -278 @Parameter(defaultValue = "${settings}", readonly = true, required = true) -279 private org.apache.maven.settings.Settings settingsXml; +278 @Parameter(property = "databaseDriverPath", defaultValue = "", required = false) +279 private String databaseDriverPath; 280 /** -281 * The security dispatcher that can decrypt passwords in the settings.xml. -282 */ -283 @Component(role = SecDispatcher.class, hint = "default") -284 private SecDispatcher securityDispatcher; -285 /** -286 * The database user name. -287 */ -288 @Parameter(property = "databaseUser", defaultValue = "", required = false) -289 private String databaseUser; -290 /** -291 * The password to use when connecting to the database. -292 */ -293 @Parameter(property = "databasePassword", defaultValue = "", required = false) -294 private String databasePassword; -295 /** -296 * A comma-separated list of file extensions to add to analysis next to jar, zip, .... -297 */ -298 @Parameter(property = "zipExtensions", required = false) -299 private String zipExtensions; -300 /** -301 * Skip Dependency Check altogether. -302 */ -303 @SuppressWarnings("CanBeFinal") -304 @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false) -305 private boolean skip = false; +281 * The server id in the settings.xml; used to retrieve encrypted passwords +282 * from the settings.xml. +283 */ +284 @Parameter(property = "serverId", defaultValue = "", required = false) +285 private String serverId; +286 /** +287 * A reference to the settings.xml settings. +288 */ +289 @Parameter(defaultValue = "${settings}", readonly = true, required = true) +290 private org.apache.maven.settings.Settings settingsXml; +291 /** +292 * The security dispatcher that can decrypt passwords in the settings.xml. +293 */ +294 @Component(role = SecDispatcher.class, hint = "default") +295 private SecDispatcher securityDispatcher; +296 /** +297 * The database user name. +298 */ +299 @Parameter(property = "databaseUser", defaultValue = "", required = false) +300 private String databaseUser; +301 /** +302 * The password to use when connecting to the database. +303 */ +304 @Parameter(property = "databasePassword", defaultValue = "", required = false) +305 private String databasePassword; 306 /** -307 * Skip Analysis for Test Scope Dependencies. -308 */ -309 @SuppressWarnings("CanBeFinal") -310 @Parameter(property = "skipTestScope", defaultValue = "true", required = false) -311 private boolean skipTestScope = true; +307 * A comma-separated list of file extensions to add to analysis next to jar, +308 * zip, .... +309 */ +310 @Parameter(property = "zipExtensions", required = false) +311 private String zipExtensions; 312 /** -313 * Skip Analysis for Runtime Scope Dependencies. +313 * Skip Dependency Check altogether. 314 */ 315 @SuppressWarnings("CanBeFinal") -316 @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false) -317 private boolean skipRuntimeScope = false; +316 @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false) +317 private boolean skip = false; 318 /** -319 * Skip Analysis for Provided Scope Dependencies. +319 * Skip Analysis for Test Scope Dependencies. 320 */ 321 @SuppressWarnings("CanBeFinal") -322 @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false) -323 private boolean skipProvidedScope = false; +322 @Parameter(property = "skipTestScope", defaultValue = "true", required = false) +323 private boolean skipTestScope = true; 324 /** -325 * The data directory, hold DC SQL DB. +325 * Skip Analysis for Runtime Scope Dependencies. 326 */ -327 @Parameter(property = "dataDirectory", defaultValue = "", required = false) -328 private String dataDirectory; -329 /** -330 * Data Mirror URL for CVE 1.2. -331 */ -332 @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false) -333 private String cveUrl12Modified; -334 /** -335 * Data Mirror URL for CVE 2.0. -336 */ -337 @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false) -338 private String cveUrl20Modified; -339 /** -340 * Base Data Mirror URL for CVE 1.2. -341 */ -342 @Parameter(property = "cveUrl12Base", defaultValue = "", required = false) -343 private String cveUrl12Base; -344 /** -345 * Data Mirror URL for CVE 2.0. -346 */ -347 @Parameter(property = "cveUrl20Base", defaultValue = "", required = false) -348 private String cveUrl20Base; -349 /** -350 * Optionally skip excessive CVE update checks for a designated duration in hours. -351 */ -352 @Parameter(property = "cveValidForHours", defaultValue = "", required = false) -353 private Integer cveValidForHours; -354 -355 /** -356 * The path to mono for .NET Assembly analysis on non-windows systems. -357 */ -358 @Parameter(property = "pathToMono", defaultValue = "", required = false) -359 private String pathToMono; -360 +327 @SuppressWarnings("CanBeFinal") +328 @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false) +329 private boolean skipRuntimeScope = false; +330 /** +331 * Skip Analysis for Provided Scope Dependencies. +332 */ +333 @SuppressWarnings("CanBeFinal") +334 @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false) +335 private boolean skipProvidedScope = false; +336 /** +337 * The data directory, hold DC SQL DB. +338 */ +339 @Parameter(property = "dataDirectory", defaultValue = "", required = false) +340 private String dataDirectory; +341 /** +342 * Data Mirror URL for CVE 1.2. +343 */ +344 @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false) +345 private String cveUrl12Modified; +346 /** +347 * Data Mirror URL for CVE 2.0. +348 */ +349 @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false) +350 private String cveUrl20Modified; +351 /** +352 * Base Data Mirror URL for CVE 1.2. +353 */ +354 @Parameter(property = "cveUrl12Base", defaultValue = "", required = false) +355 private String cveUrl12Base; +356 /** +357 * Data Mirror URL for CVE 2.0. +358 */ +359 @Parameter(property = "cveUrl20Base", defaultValue = "", required = false) +360 private String cveUrl20Base; 361 /** -362 * The Proxy URL. -363 * -364 * @deprecated Please use mavenSettings instead -365 */ -366 @SuppressWarnings("CanBeFinal") -367 @Parameter(property = "proxyUrl", defaultValue = "", required = false) -368 @Deprecated -369 private String proxyUrl = null; -370 /** -371 * Sets whether or not the external report format should be used. -372 * -373 * @deprecated the internal report is no longer supported -374 */ -375 @SuppressWarnings("CanBeFinal") -376 @Parameter(property = "externalReport") -377 @Deprecated -378 private String externalReport = null; -379 // </editor-fold> -380 //<editor-fold defaultstate="collapsed" desc="Base Maven implementation"> -381 -382 /** -383 * Executes dependency-check. -384 * -385 * @throws MojoExecutionException thrown if there is an exception executing the mojo -386 * @throws MojoFailureException thrown if dependency-check failed the build +362 * Optionally skip excessive CVE update checks for a designated duration in +363 * hours. +364 */ +365 @Parameter(property = "cveValidForHours", defaultValue = "", required = false) +366 private Integer cveValidForHours; +367 +368 /** +369 * The path to mono for .NET Assembly analysis on non-windows systems. +370 */ +371 @Parameter(property = "pathToMono", defaultValue = "", required = false) +372 private String pathToMono; +373 +374 /** +375 * The Proxy URL. +376 * +377 * @deprecated Please use mavenSettings instead +378 */ +379 @SuppressWarnings("CanBeFinal") +380 @Parameter(property = "proxyUrl", defaultValue = "", required = false) +381 @Deprecated +382 private String proxyUrl = null; +383 /** +384 * Sets whether or not the external report format should be used. +385 * +386 * @deprecated the internal report is no longer supported 387 */ -388 @Override -389 public void execute() throws MojoExecutionException, MojoFailureException { -390 generatingSite = false; -391 if (skip) { -392 getLog().info("Skipping " + getName(Locale.US)); -393 } else { -394 validateAggregate(); -395 project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory); -396 runCheck(); -397 } -398 } -399 -400 /** -401 * Checks if the aggregate configuration parameter has been set to true. If it has a MojoExecutionException is thrown because -402 * the aggregate configuration parameter is no longer supported. -403 * -404 * @throws MojoExecutionException thrown if aggregate is set to true -405 */ -406 private void validateAggregate() throws MojoExecutionException { -407 if (aggregate != null && aggregate) { -408 final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. " -409 + "Please use the aggregate goal instead."; -410 throw new MojoExecutionException(msg); +388 @SuppressWarnings("CanBeFinal") +389 @Parameter(property = "externalReport") +390 @Deprecated +391 private String externalReport = null; +392 // </editor-fold> +393 //<editor-fold defaultstate="collapsed" desc="Base Maven implementation"> +394 +395 /** +396 * Executes dependency-check. +397 * +398 * @throws MojoExecutionException thrown if there is an exception executing +399 * the mojo +400 * @throws MojoFailureException thrown if dependency-check failed the build +401 */ +402 @Override +403 public void execute() throws MojoExecutionException, MojoFailureException { +404 generatingSite = false; +405 if (skip) { +406 getLog().info("Skipping " + getName(Locale.US)); +407 } else { +408 validateAggregate(); +409 project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory); +410 runCheck(); 411 } 412 } 413 414 /** -415 * Generates the Dependency-Check Site Report. -416 * -417 * @param sink the sink to write the report to -418 * @param locale the locale to use when generating the report -419 * @throws MavenReportException if a maven report exception occurs -420 * @deprecated use {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} instead. -421 */ -422 @Override -423 @Deprecated -424 public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { -425 generate((Sink) sink, locale); -426 } -427 -428 /** -429 * A flag indicating whether or not the maven site is being generated. -430 */ -431 private boolean generatingSite = false; -432 -433 /** -434 * Returns true if the Maven site is being generated. -435 * -436 * @return true if the Maven site is being generated -437 */ -438 protected boolean isGeneratingSite() { -439 return generatingSite; -440 } -441 -442 /** -443 * Generates the Dependency-Check Site Report. -444 * -445 * @param sink the sink to write the report to -446 * @param locale the locale to use when generating the report -447 * @throws MavenReportException if a maven report exception occurs -448 */ -449 public void generate(Sink sink, Locale locale) throws MavenReportException { -450 generatingSite = true; -451 try { -452 validateAggregate(); -453 } catch (MojoExecutionException ex) { -454 throw new MavenReportException(ex.getMessage()); -455 } -456 project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory()); -457 try { -458 runCheck(); -459 } catch (MojoExecutionException ex) { -460 throw new MavenReportException(ex.getMessage(), ex); -461 } catch (MojoFailureException ex) { -462 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build"); -463 } -464 } -465 -466 /** -467 * Returns the correct output directory depending on if a site is being executed or not. -468 * -469 * @return the directory to write the report(s) -470 * @throws MojoExecutionException thrown if there is an error loading the file path -471 */ -472 protected File getCorrectOutputDirectory() throws MojoExecutionException { -473 return getCorrectOutputDirectory(this.project); -474 } -475 -476 /** -477 * Returns the correct output directory depending on if a site is being executed or not. -478 * -479 * @param current the Maven project to get the output directory from -480 * @return the directory to write the report(s) -481 */ -482 protected File getCorrectOutputDirectory(MavenProject current) { -483 final Object obj = current.getContextValue(getOutputDirectoryContextKey()); -484 if (obj != null && obj instanceof File) { -485 return (File) obj; -486 } -487 File target = new File(current.getBuild().getDirectory()); -488 if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) { -489 target = target.getParentFile(); -490 } -491 return target; -492 } -493 -494 /** -495 * Returns the correct output directory depending on if a site is being executed or not. -496 * -497 * @param current the Maven project to get the output directory from -498 * @return the directory to write the report(s) -499 */ -500 protected File getDataFile(MavenProject current) { -501 if (getLog().isDebugEnabled()) { -502 getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey())); -503 } -504 final Object obj = current.getContextValue(getDataFileContextKey()); -505 if (obj != null) { -506 if (obj instanceof String) { -507 final File f = new File((String) obj); -508 return f; -509 } -510 } else { -511 if (getLog().isDebugEnabled()) { -512 getLog().debug("Context value not found"); -513 } -514 } -515 return null; -516 } -517 -518 /** -519 * Scans the project's artifacts and adds them to the engine's dependency list. -520 * -521 * @param project the project to scan the dependencies of -522 * @param engine the engine to use to scan the dependencies -523 */ -524 protected void scanArtifacts(MavenProject project, Engine engine) { -525 for (Artifact a : project.getArtifacts()) { -526 if (excludeFromScan(a)) { -527 continue; -528 } -529 final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile()); -530 if (deps != null) { -531 if (deps.size() == 1) { -532 final Dependency d = deps.get(0); -533 if (d != null) { -534 final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion()); -535 d.addAsEvidence("pom", ma, Confidence.HIGHEST); -536 d.addProjectReference(project.getName()); -537 if (getLog().isDebugEnabled()) { -538 getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(), -539 d.getDisplayFileName())); -540 } -541 } -542 } else { -543 if (getLog().isDebugEnabled()) { -544 final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", -545 a.getGroupId(), a.getArtifactId(), a.getVersion()); -546 getLog().debug(msg); -547 } -548 } -549 } -550 } -551 } -552 -553 /** -554 * Executes the dependency-check scan and generates the necassary report. -555 * -556 * @throws MojoExecutionException thrown if there is an exception running the scan -557 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -558 */ -559 public abstract void runCheck() throws MojoExecutionException, MojoFailureException; -560 -561 /** -562 * Sets the Reporting output directory. -563 * -564 * @param directory the output directory -565 */ -566 @Override -567 public void setReportOutputDirectory(File directory) { -568 reportOutputDirectory = directory; +415 * Checks if the aggregate configuration parameter has been set to true. If +416 * it has a MojoExecutionException is thrown because the aggregate +417 * configuration parameter is no longer supported. +418 * +419 * @throws MojoExecutionException thrown if aggregate is set to true +420 */ +421 private void validateAggregate() throws MojoExecutionException { +422 if (aggregate != null && aggregate) { +423 final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. " +424 + "Please use the aggregate goal instead."; +425 throw new MojoExecutionException(msg); +426 } +427 } +428 +429 /** +430 * Generates the Dependency-Check Site Report. +431 * +432 * @param sink the sink to write the report to +433 * @param locale the locale to use when generating the report +434 * @throws MavenReportException if a maven report exception occurs +435 * @deprecated use +436 * {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} +437 * instead. +438 */ +439 @Override +440 @Deprecated +441 public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { +442 generate((Sink) sink, locale); +443 } +444 +445 /** +446 * A flag indicating whether or not the maven site is being generated. +447 */ +448 private boolean generatingSite = false; +449 +450 /** +451 * Returns true if the Maven site is being generated. +452 * +453 * @return true if the Maven site is being generated +454 */ +455 protected boolean isGeneratingSite() { +456 return generatingSite; +457 } +458 +459 /** +460 * Generates the Dependency-Check Site Report. +461 * +462 * @param sink the sink to write the report to +463 * @param locale the locale to use when generating the report +464 * @throws MavenReportException if a maven report exception occurs +465 */ +466 public void generate(Sink sink, Locale locale) throws MavenReportException { +467 generatingSite = true; +468 try { +469 validateAggregate(); +470 } catch (MojoExecutionException ex) { +471 throw new MavenReportException(ex.getMessage()); +472 } +473 project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory()); +474 try { +475 runCheck(); +476 } catch (MojoExecutionException ex) { +477 throw new MavenReportException(ex.getMessage(), ex); +478 } catch (MojoFailureException ex) { +479 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build"); +480 } +481 } +482 +483 /** +484 * Returns the correct output directory depending on if a site is being +485 * executed or not. +486 * +487 * @return the directory to write the report(s) +488 * @throws MojoExecutionException thrown if there is an error loading the +489 * file path +490 */ +491 protected File getCorrectOutputDirectory() throws MojoExecutionException { +492 return getCorrectOutputDirectory(this.project); +493 } +494 +495 /** +496 * Returns the correct output directory depending on if a site is being +497 * executed or not. +498 * +499 * @param current the Maven project to get the output directory from +500 * @return the directory to write the report(s) +501 */ +502 protected File getCorrectOutputDirectory(MavenProject current) { +503 final Object obj = current.getContextValue(getOutputDirectoryContextKey()); +504 if (obj != null && obj instanceof File) { +505 return (File) obj; +506 } +507 File target = new File(current.getBuild().getDirectory()); +508 if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) { +509 target = target.getParentFile(); +510 } +511 return target; +512 } +513 +514 /** +515 * Returns the correct output directory depending on if a site is being +516 * executed or not. +517 * +518 * @param current the Maven project to get the output directory from +519 * @return the directory to write the report(s) +520 */ +521 protected File getDataFile(MavenProject current) { +522 if (getLog().isDebugEnabled()) { +523 getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey())); +524 } +525 final Object obj = current.getContextValue(getDataFileContextKey()); +526 if (obj != null) { +527 if (obj instanceof String) { +528 final File f = new File((String) obj); +529 return f; +530 } +531 } else if (getLog().isDebugEnabled()) { +532 getLog().debug("Context value not found"); +533 } +534 return null; +535 } +536 +537 /** +538 * Scans the project's artifacts and adds them to the engine's dependency +539 * list. +540 * +541 * @param project the project to scan the dependencies of +542 * @param engine the engine to use to scan the dependencies +543 */ +544 protected void scanArtifacts(MavenProject project, Engine engine) { +545 for (Artifact a : project.getArtifacts()) { +546 if (excludeFromScan(a)) { +547 continue; +548 } +549 final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile()); +550 if (deps != null) { +551 if (deps.size() == 1) { +552 final Dependency d = deps.get(0); +553 if (d != null) { +554 final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion()); +555 d.addAsEvidence("pom", ma, Confidence.HIGHEST); +556 d.addProjectReference(project.getName()); +557 if (getLog().isDebugEnabled()) { +558 getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(), +559 d.getDisplayFileName())); +560 } +561 } +562 } else if (getLog().isDebugEnabled()) { +563 final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", +564 a.getGroupId(), a.getArtifactId(), a.getVersion()); +565 getLog().debug(msg); +566 } +567 } +568 } 569 } 570 571 /** -572 * Returns the report output directory. +572 * Executes the dependency-check scan and generates the necassary report. 573 * -574 * @return the report output directory -575 */ -576 @Override -577 public File getReportOutputDirectory() { -578 return reportOutputDirectory; -579 } +574 * @throws MojoExecutionException thrown if there is an exception running +575 * the scan +576 * @throws MojoFailureException thrown if dependency-check is configured to +577 * fail the build +578 */ +579 public abstract void runCheck() throws MojoExecutionException, MojoFailureException; 580 581 /** -582 * Returns the output directory. +582 * Sets the Reporting output directory. 583 * -584 * @return the output directory +584 * @param directory the output directory 585 */ -586 public File getOutputDirectory() { -587 return outputDirectory; -588 } -589 -590 /** -591 * Returns whether this is an external report. This method always returns true. -592 * -593 * @return <code>true</code> -594 */ -595 @Override -596 public final boolean isExternalReport() { -597 return true; -598 } -599 -600 /** -601 * Returns the output name. -602 * -603 * @return the output name -604 */ -605 @Override -606 public String getOutputName() { -607 if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) { -608 return "dependency-check-report"; -609 } else if ("XML".equalsIgnoreCase(this.format)) { -610 return "dependency-check-report.xml#"; -611 } else if ("VULN".equalsIgnoreCase(this.format)) { -612 return "dependency-check-vulnerability"; -613 } else { -614 getLog().warn("Unknown report format used during site generation."); -615 return "dependency-check-report"; -616 } -617 } -618 -619 /** -620 * Returns the category name. -621 * -622 * @return the category name -623 */ -624 @Override -625 public String getCategoryName() { -626 return MavenReport.CATEGORY_PROJECT_REPORTS; -627 } -628 //</editor-fold> -629 -630 /** -631 * Initializes a new <code>Engine</code> that can be used for scanning. -632 * -633 * @return a newly instantiated <code>Engine</code> -634 * @throws DatabaseException thrown if there is a database exception -635 */ -636 protected Engine initializeEngine() throws DatabaseException { -637 populateSettings(); -638 return new Engine(this.project, -639 this.reactorProjects); -640 } -641 -642 /** -643 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -644 * required to change the proxy url, port, and connection timeout. -645 */ -646 protected void populateSettings() { -647 Settings.initialize(); -648 InputStream mojoProperties = null; -649 try { -650 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); -651 Settings.mergeProperties(mojoProperties); -652 } catch (IOException ex) { -653 getLog().warn("Unable to load the dependency-check ant task.properties file."); -654 if (getLog().isDebugEnabled()) { -655 getLog().debug("", ex); -656 } -657 } finally { -658 if (mojoProperties != null) { -659 try { -660 mojoProperties.close(); -661 } catch (IOException ex) { -662 if (getLog().isDebugEnabled()) { -663 getLog().debug("", ex); -664 } -665 } -666 } -667 } -668 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); -669 -670 if (externalReport != null) { -671 getLog().warn("The 'externalReport' option was set; this configuration option has been removed. " -672 + "Please update the dependency-check-maven plugin's configuration"); -673 } -674 -675 if (proxyUrl != null && !proxyUrl.isEmpty()) { -676 getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead"); -677 } -678 final Proxy proxy = getMavenProxy(); -679 if (proxy != null) { -680 Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); -681 Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); -682 final String userName = proxy.getUsername(); -683 final String password = proxy.getPassword(); -684 Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName); -685 Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password); -686 Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts()); -687 } -688 -689 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -690 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +586 @Override +587 public void setReportOutputDirectory(File directory) { +588 reportOutputDirectory = directory; +589 } +590 +591 /** +592 * Returns the report output directory. +593 * +594 * @return the report output directory +595 */ +596 @Override +597 public File getReportOutputDirectory() { +598 return reportOutputDirectory; +599 } +600 +601 /** +602 * Returns the output directory. +603 * +604 * @return the output directory +605 */ +606 public File getOutputDirectory() { +607 return outputDirectory; +608 } +609 +610 /** +611 * Returns whether this is an external report. This method always returns +612 * true. +613 * +614 * @return <code>true</code> +615 */ +616 @Override +617 public final boolean isExternalReport() { +618 return true; +619 } +620 +621 /** +622 * Returns the output name. +623 * +624 * @return the output name +625 */ +626 @Override +627 public String getOutputName() { +628 if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) { +629 return "dependency-check-report"; +630 } else if ("XML".equalsIgnoreCase(this.format)) { +631 return "dependency-check-report.xml#"; +632 } else if ("VULN".equalsIgnoreCase(this.format)) { +633 return "dependency-check-vulnerability"; +634 } else { +635 getLog().warn("Unknown report format used during site generation."); +636 return "dependency-check-report"; +637 } +638 } +639 +640 /** +641 * Returns the category name. +642 * +643 * @return the category name +644 */ +645 @Override +646 public String getCategoryName() { +647 return MavenReport.CATEGORY_PROJECT_REPORTS; +648 } +649 //</editor-fold> +650 +651 /** +652 * Initializes a new <code>Engine</code> that can be used for scanning. +653 * +654 * @return a newly instantiated <code>Engine</code> +655 * @throws DatabaseException thrown if there is a database exception +656 */ +657 protected Engine initializeEngine() throws DatabaseException { +658 populateSettings(); +659 return new Engine(this.project, +660 this.reactorProjects); +661 } +662 +663 /** +664 * Takes the properties supplied and updates the dependency-check settings. +665 * Additionally, this sets the system properties required to change the +666 * proxy url, port, and connection timeout. +667 */ +668 protected void populateSettings() { +669 Settings.initialize(); +670 InputStream mojoProperties = null; +671 try { +672 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); +673 Settings.mergeProperties(mojoProperties); +674 } catch (IOException ex) { +675 getLog().warn("Unable to load the dependency-check ant task.properties file."); +676 if (getLog().isDebugEnabled()) { +677 getLog().debug("", ex); +678 } +679 } finally { +680 if (mojoProperties != null) { +681 try { +682 mojoProperties.close(); +683 } catch (IOException ex) { +684 if (getLog().isDebugEnabled()) { +685 getLog().debug("", ex); +686 } +687 } +688 } +689 } +690 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); 691 -692 //File Type Analyzer Settings -693 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); -694 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); -695 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -696 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -697 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -698 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -699 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); -700 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); -701 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -702 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -703 -704 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); -705 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); -706 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); -707 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); -708 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); -709 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); -710 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); -711 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +692 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); +693 +694 if (externalReport != null) { +695 getLog().warn("The 'externalReport' option was set; this configuration option has been removed. " +696 + "Please update the dependency-check-maven plugin's configuration"); +697 } +698 +699 if (proxyUrl != null && !proxyUrl.isEmpty()) { +700 getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead"); +701 } +702 final Proxy proxy = getMavenProxy(); +703 if (proxy != null) { +704 Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); +705 Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); +706 final String userName = proxy.getUsername(); +707 final String password = proxy.getPassword(); +708 Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName); +709 Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password); +710 Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts()); +711 } 712 -713 //Database configuration -714 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -715 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -716 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -717 -718 if (databaseUser == null && databasePassword == null && serverId != null) { -719 final Server server = settingsXml.getServer(serverId); -720 if (server != null) { -721 databaseUser = server.getUsername(); -722 try { -723 //The following fix was copied from: -724 // https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java -725 // -726 // FIX to resolve -727 // org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: -728 // java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory) -729 // -730 if (securityDispatcher instanceof DefaultSecDispatcher) { -731 ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml"); -732 } -733 -734 databasePassword = securityDispatcher.decrypt(server.getPassword()); -735 } catch (SecDispatcherException ex) { -736 if (ex.getCause() instanceof FileNotFoundException -737 || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) { -738 //maybe its not encrypted? -739 final String tmp = server.getPassword(); -740 if (tmp.startsWith("{") && tmp.endsWith("}")) { -741 getLog().error(String.format( -742 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", -743 serverId, ex.getMessage())); -744 } else { -745 databasePassword = tmp; -746 } -747 } else { -748 getLog().error(String.format( -749 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", -750 serverId, ex.getMessage())); -751 } -752 } -753 } else { -754 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId)); -755 } -756 } +713 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +714 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +715 +716 //File Type Analyzer Settings +717 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); +718 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); +719 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +720 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +721 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +722 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +723 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); +724 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); +725 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +726 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +727 +728 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); +729 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); +730 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); +731 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); +732 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); +733 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); +734 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); +735 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +736 +737 //Database configuration +738 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +739 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +740 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +741 +742 if (databaseUser == null && databasePassword == null && serverId != null) { +743 final Server server = settingsXml.getServer(serverId); +744 if (server != null) { +745 databaseUser = server.getUsername(); +746 try { +747 //The following fix was copied from: +748 // https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java +749 // +750 // FIX to resolve +751 // org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: +752 // java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory) +753 // +754 if (securityDispatcher instanceof DefaultSecDispatcher) { +755 ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml"); +756 } 757 -758 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -759 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -760 Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -761 -762 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); -763 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); -764 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); -765 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); -766 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -767 -768 } -769 -770 /** -771 * Returns the maven proxy. -772 * -773 * @return the maven proxy -774 */ -775 private Proxy getMavenProxy() { -776 if (mavenSettings != null) { -777 final List<Proxy> proxies = mavenSettings.getProxies(); -778 if (proxies != null && !proxies.isEmpty()) { -779 if (mavenSettingsProxyId != null) { -780 for (Proxy proxy : proxies) { -781 if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) { -782 return proxy; -783 } -784 } -785 } else if (proxies.size() == 1) { -786 return proxies.get(0); -787 } else { -788 getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check " -789 + "configuration set the mavenSettingsProxyId so that the correct proxy will be used."); -790 throw new IllegalStateException("Ambiguous proxy definition"); -791 } -792 } -793 } -794 return null; -795 } -796 -797 /** -798 * Tests is the artifact should be included in the scan (i.e. is the dependency in a scope that is being scanned). -799 * -800 * @param a the Artifact to test -801 * @return <code>true</code> if the artifact is in an excluded scope; otherwise <code>false</code> -802 */ -803 protected boolean excludeFromScan(Artifact a) { -804 if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { -805 return true; -806 } -807 if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) { -808 return true; -809 } -810 if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) { -811 return true; -812 } -813 return false; -814 } -815 -816 /** -817 * Returns a reference to the current project. This method is used instead of auto-binding the project via component -818 * annotation in concrete implementations of this. If the child has a <code>@Component MavenProject project;</code> defined -819 * then the abstract class (i.e. this class) will not have access to the current project (just the way Maven works with the -820 * binding). -821 * -822 * @return returns a reference to the current project -823 */ -824 protected MavenProject getProject() { -825 return project; -826 } -827 -828 /** -829 * Returns the list of Maven Projects in this build. -830 * -831 * @return the list of Maven Projects in this build -832 */ -833 protected List<MavenProject> getReactorProjects() { -834 return reactorProjects; -835 } -836 -837 /** -838 * Returns the report format. -839 * -840 * @return the report format -841 */ -842 protected String getFormat() { -843 return format; -844 } -845 -846 /** -847 * Generates the reports for a given dependency-check engine. -848 * -849 * @param engine a dependency-check engine -850 * @param p the maven project -851 * @param outputDir the directory path to write the report(s). -852 */ -853 protected void writeReports(Engine engine, MavenProject p, File outputDir) { -854 DatabaseProperties prop = null; -855 CveDB cve = null; -856 try { -857 cve = new CveDB(); -858 cve.open(); -859 prop = cve.getDatabaseProperties(); -860 } catch (DatabaseException ex) { -861 if (getLog().isDebugEnabled()) { -862 getLog().debug("Unable to retrieve DB Properties", ex); -863 } -864 } finally { -865 if (cve != null) { -866 cve.close(); -867 } -868 } -869 final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); -870 try { -871 r.generateReports(outputDir.getAbsolutePath(), format); -872 } catch (IOException ex) { -873 getLog().error( -874 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -875 if (getLog().isDebugEnabled()) { -876 getLog().debug("", ex); -877 } -878 } catch (Throwable ex) { -879 getLog().error( -880 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -881 if (getLog().isDebugEnabled()) { -882 getLog().debug("", ex); -883 } -884 } -885 } -886 -887 //<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary"> -888 /** -889 * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the -890 * configuration. -891 * -892 * @param dependencies the list of dependency objects -893 * @throws MojoFailureException thrown if a CVSS score is found that is higher then the threshold set -894 */ -895 protected void checkForFailure(List<Dependency> dependencies) throws MojoFailureException { -896 if (failBuildOnCVSS <= 10) { -897 final StringBuilder ids = new StringBuilder(); -898 for (Dependency d : dependencies) { -899 boolean addName = true; -900 for (Vulnerability v : d.getVulnerabilities()) { -901 if (v.getCvssScore() >= failBuildOnCVSS) { -902 if (addName) { -903 addName = false; -904 ids.append(NEW_LINE).append(d.getFileName()).append(": "); -905 ids.append(v.getName()); -906 } else { -907 ids.append(", ").append(v.getName()); -908 } -909 } -910 } +758 databasePassword = securityDispatcher.decrypt(server.getPassword()); +759 } catch (SecDispatcherException ex) { +760 if (ex.getCause() instanceof FileNotFoundException +761 || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) { +762 //maybe its not encrypted? +763 final String tmp = server.getPassword(); +764 if (tmp.startsWith("{") && tmp.endsWith("}")) { +765 getLog().error(String.format( +766 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", +767 serverId, ex.getMessage())); +768 } else { +769 databasePassword = tmp; +770 } +771 } else { +772 getLog().error(String.format( +773 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", +774 serverId, ex.getMessage())); +775 } +776 } +777 } else { +778 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId)); +779 } +780 } +781 +782 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +783 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +784 Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +785 +786 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); +787 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); +788 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); +789 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); +790 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +791 +792 } +793 +794 /** +795 * Returns the maven proxy. +796 * +797 * @return the maven proxy +798 */ +799 private Proxy getMavenProxy() { +800 if (mavenSettings != null) { +801 final List<Proxy> proxies = mavenSettings.getProxies(); +802 if (proxies != null && !proxies.isEmpty()) { +803 if (mavenSettingsProxyId != null) { +804 for (Proxy proxy : proxies) { +805 if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) { +806 return proxy; +807 } +808 } +809 } else if (proxies.size() == 1) { +810 return proxies.get(0); +811 } else { +812 getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check " +813 + "configuration set the mavenSettingsProxyId so that the correct proxy will be used."); +814 throw new IllegalStateException("Ambiguous proxy definition"); +815 } +816 } +817 } +818 return null; +819 } +820 +821 /** +822 * Tests is the artifact should be included in the scan (i.e. is the +823 * dependency in a scope that is being scanned). +824 * +825 * @param a the Artifact to test +826 * @return <code>true</code> if the artifact is in an excluded scope; +827 * otherwise <code>false</code> +828 */ +829 protected boolean excludeFromScan(Artifact a) { +830 if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { +831 return true; +832 } +833 if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) { +834 return true; +835 } +836 if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) { +837 return true; +838 } +839 return false; +840 } +841 +842 /** +843 * Returns a reference to the current project. This method is used instead +844 * of auto-binding the project via component annotation in concrete +845 * implementations of this. If the child has a +846 * <code>@Component MavenProject project;</code> defined then the abstract +847 * class (i.e. this class) will not have access to the current project (just +848 * the way Maven works with the binding). +849 * +850 * @return returns a reference to the current project +851 */ +852 protected MavenProject getProject() { +853 return project; +854 } +855 +856 /** +857 * Returns the list of Maven Projects in this build. +858 * +859 * @return the list of Maven Projects in this build +860 */ +861 protected List<MavenProject> getReactorProjects() { +862 return reactorProjects; +863 } +864 +865 /** +866 * Returns the report format. +867 * +868 * @return the report format +869 */ +870 protected String getFormat() { +871 return format; +872 } +873 +874 /** +875 * Generates the reports for a given dependency-check engine. +876 * +877 * @param engine a dependency-check engine +878 * @param p the maven project +879 * @param outputDir the directory path to write the report(s). +880 */ +881 protected void writeReports(Engine engine, MavenProject p, File outputDir) { +882 DatabaseProperties prop = null; +883 CveDB cve = null; +884 try { +885 cve = new CveDB(); +886 cve.open(); +887 prop = cve.getDatabaseProperties(); +888 } catch (DatabaseException ex) { +889 if (getLog().isDebugEnabled()) { +890 getLog().debug("Unable to retrieve DB Properties", ex); +891 } +892 } finally { +893 if (cve != null) { +894 cve.close(); +895 } +896 } +897 final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); +898 try { +899 r.generateReports(outputDir.getAbsolutePath(), format); +900 } catch (IOException ex) { +901 getLog().error( +902 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); +903 if (getLog().isDebugEnabled()) { +904 getLog().debug("", ex); +905 } +906 } catch (Throwable ex) { +907 getLog().error( +908 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); +909 if (getLog().isDebugEnabled()) { +910 getLog().debug("", ex); 911 } -912 if (ids.length() > 0) { -913 final String msg = String.format("%n%nDependency-Check Failure:%n" -914 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -915 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -916 throw new MojoFailureException(msg); -917 } -918 } -919 } -920 -921 /** -922 * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. -923 * -924 * @param mp the Maven project for which the summary is shown -925 * @param dependencies a list of dependency objects -926 */ -927 protected void showSummary(MavenProject mp, List<Dependency> dependencies) { -928 if (showSummary) { -929 final StringBuilder summary = new StringBuilder(); -930 for (Dependency d : dependencies) { -931 boolean firstEntry = true; -932 final StringBuilder ids = new StringBuilder(); -933 for (Vulnerability v : d.getVulnerabilities()) { -934 if (firstEntry) { -935 firstEntry = false; -936 } else { -937 ids.append(", "); +912 } +913 } +914 +915 //<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary"> +916 /** +917 * Checks to see if a vulnerability has been identified with a CVSS score +918 * that is above the threshold set in the configuration. +919 * +920 * @param dependencies the list of dependency objects +921 * @throws MojoFailureException thrown if a CVSS score is found that is +922 * higher then the threshold set +923 */ +924 protected void checkForFailure(List<Dependency> dependencies) throws MojoFailureException { +925 if (failBuildOnCVSS <= 10) { +926 final StringBuilder ids = new StringBuilder(); +927 for (Dependency d : dependencies) { +928 boolean addName = true; +929 for (Vulnerability v : d.getVulnerabilities()) { +930 if (v.getCvssScore() >= failBuildOnCVSS) { +931 if (addName) { +932 addName = false; +933 ids.append(NEW_LINE).append(d.getFileName()).append(": "); +934 ids.append(v.getName()); +935 } else { +936 ids.append(", ").append(v.getName()); +937 } 938 } -939 ids.append(v.getName()); -940 } -941 if (ids.length() > 0) { -942 summary.append(d.getFileName()).append(" ("); -943 firstEntry = true; -944 for (Identifier id : d.getIdentifiers()) { -945 if (firstEntry) { -946 firstEntry = false; -947 } else { -948 summary.append(", "); -949 } -950 summary.append(id.getValue()); -951 } -952 summary.append(") : ").append(ids).append(NEW_LINE); -953 } -954 } -955 if (summary.length() > 0) { -956 final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s" -957 + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString()); -958 getLog().warn(msg); -959 } -960 } -961 } -962 -963 //</editor-fold> -964 //<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file"> -965 /** -966 * Returns the key used to store the path to the data file that is saved by <code>writeDataFile()</code>. This key is used in -967 * the <code>MavenProject.(set|get)ContextValue</code>. -968 * -969 * @return the key used to store the path to the data file -970 */ -971 protected String getDataFileContextKey() { -972 return "dependency-check-path-" + dataFileName; -973 } -974 -975 /** -976 * Returns the key used to store the path to the output directory. When generating the report in the -977 * <code>executeAggregateReport()</code> the output directory should be obtained by using this key. -978 * -979 * @return the key used to store the path to the output directory -980 */ -981 protected String getOutputDirectoryContextKey() { -982 return "dependency-output-dir-" + dataFileName; -983 } -984 -985 /** -986 * Writes the scan data to disk. This is used to serialize the scan data between the "check" and "aggregate" phase. -987 * -988 * @param mp the mMven project for which the data file was created -989 * @param writeTo the directory to write the data file -990 * @param dependencies the list of dependencies to serialize -991 */ -992 protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) { -993 File file; -994 //check to see if this was already written out -995 if (mp.getContextValue(this.getDataFileContextKey()) == null) { -996 if (writeTo == null) { -997 file = new File(mp.getBuild().getDirectory()); -998 file = new File(file, dataFileName); -999 } else { -1000 file = new File(writeTo, dataFileName); -1001 } -1002 final File parent = file.getParentFile(); -1003 if (!parent.isDirectory() && parent.mkdirs()) { -1004 getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", -1005 parent.getAbsolutePath())); -1006 } -1007 -1008 ObjectOutputStream out = null; -1009 try { -1010 if (dependencies != null) { -1011 out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); -1012 out.writeObject(dependencies); -1013 } -1014 if (getLog().isDebugEnabled()) { -1015 getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s", -1016 file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey())); -1017 } -1018 mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath()); -1019 } catch (IOException ex) { -1020 getLog().warn("Unable to create data file used for report aggregation; " -1021 + "if report aggregation is being used the results may be incomplete."); -1022 if (getLog().isDebugEnabled()) { -1023 getLog().debug(ex.getMessage(), ex); -1024 } -1025 } finally { -1026 if (out != null) { -1027 try { -1028 out.close(); -1029 } catch (IOException ex) { -1030 if (getLog().isDebugEnabled()) { -1031 getLog().debug("ignore", ex); -1032 } -1033 } -1034 } -1035 } -1036 } -1037 } -1038 -1039 /** -1040 * Reads the serialized scan data from disk. This is used to serialize the scan data between the "check" and "aggregate" -1041 * phase. -1042 * -1043 * @param project the Maven project to read the data file from -1044 * @return a <code>Engine</code> object populated with dependencies if the serialized data file exists; otherwise -1045 * <code>null</code> is returned -1046 */ -1047 protected List<Dependency> readDataFile(MavenProject project) { -1048 final Object oPath = project.getContextValue(this.getDataFileContextKey()); -1049 if (oPath == null) { -1050 return null; -1051 } -1052 List<Dependency> ret = null; -1053 final String path = (String) oPath; -1054 //ObjectInputStream ois = null; -1055 ExpectedOjectInputStream ois = null; -1056 try { -1057 //ois = new ObjectInputStream(new FileInputStream(path)); -1058 ois = new ExpectedOjectInputStream(new FileInputStream(path), -1059 "java.util.ArrayList", -1060 "java.util.HashSet", -1061 "java.util.TreeSet", -1062 "java.lang.AbstractSet", -1063 "java.lang.AbstractCollection", -1064 "java.lang.Enum", -1065 "org.owasp.dependencycheck.dependency.Confidence", -1066 "org.owasp.dependencycheck.dependency.Dependency", -1067 "org.owasp.dependencycheck.dependency.Evidence", -1068 "org.owasp.dependencycheck.dependency.EvidenceCollection", -1069 "org.owasp.dependencycheck.dependency.Identifier", -1070 "org.owasp.dependencycheck.dependency.Reference", -1071 "org.owasp.dependencycheck.dependency.Vulnerability", -1072 "org.owasp.dependencycheck.dependency.VulnerabilityComparator", -1073 "org.owasp.dependencycheck.dependency.VulnerableSoftware", -1074 "org.owasp.dependencycheck.data.cpe.IndexEntry"); -1075 ret = (List<Dependency>) ois.readObject(); -1076 } catch (FileNotFoundException ex) { -1077 //TODO fix logging -1078 getLog().error("", ex); -1079 } catch (IOException ex) { -1080 getLog().error("", ex); -1081 } catch (ClassNotFoundException ex) { -1082 getLog().error("", ex); -1083 } finally { -1084 if (ois != null) { -1085 try { -1086 ois.close(); -1087 } catch (IOException ex) { -1088 getLog().error("", ex); -1089 } -1090 } -1091 } -1092 return ret; -1093 } -1094 //</editor-fold> -1095 } +939 } +940 } +941 if (ids.length() > 0) { +942 final String msg = String.format("%n%nDependency-Check Failure:%n" +943 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +944 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +945 throw new MojoFailureException(msg); +946 } +947 } +948 } +949 +950 /** +951 * Generates a warning message listing a summary of dependencies and their +952 * associated CPE and CVE entries. +953 * +954 * @param mp the Maven project for which the summary is shown +955 * @param dependencies a list of dependency objects +956 */ +957 protected void showSummary(MavenProject mp, List<Dependency> dependencies) { +958 if (showSummary) { +959 final StringBuilder summary = new StringBuilder(); +960 for (Dependency d : dependencies) { +961 boolean firstEntry = true; +962 final StringBuilder ids = new StringBuilder(); +963 for (Vulnerability v : d.getVulnerabilities()) { +964 if (firstEntry) { +965 firstEntry = false; +966 } else { +967 ids.append(", "); +968 } +969 ids.append(v.getName()); +970 } +971 if (ids.length() > 0) { +972 summary.append(d.getFileName()).append(" ("); +973 firstEntry = true; +974 for (Identifier id : d.getIdentifiers()) { +975 if (firstEntry) { +976 firstEntry = false; +977 } else { +978 summary.append(", "); +979 } +980 summary.append(id.getValue()); +981 } +982 summary.append(") : ").append(ids).append(NEW_LINE); +983 } +984 } +985 if (summary.length() > 0) { +986 final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s" +987 + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString()); +988 getLog().warn(msg); +989 } +990 } +991 } +992 +993 //</editor-fold> +994 //<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file"> +995 /** +996 * Returns the key used to store the path to the data file that is saved by +997 * <code>writeDataFile()</code>. This key is used in the +998 * <code>MavenProject.(set|get)ContextValue</code>. +999 * +1000 * @return the key used to store the path to the data file +1001 */ +1002 protected String getDataFileContextKey() { +1003 return "dependency-check-path-" + dataFileName; +1004 } +1005 +1006 /** +1007 * Returns the key used to store the path to the output directory. When +1008 * generating the report in the <code>executeAggregateReport()</code> the +1009 * output directory should be obtained by using this key. +1010 * +1011 * @return the key used to store the path to the output directory +1012 */ +1013 protected String getOutputDirectoryContextKey() { +1014 return "dependency-output-dir-" + dataFileName; +1015 } +1016 +1017 /** +1018 * Writes the scan data to disk. This is used to serialize the scan data +1019 * between the "check" and "aggregate" phase. +1020 * +1021 * @param mp the mMven project for which the data file was created +1022 * @param writeTo the directory to write the data file +1023 * @param dependencies the list of dependencies to serialize +1024 */ +1025 protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) { +1026 File file; +1027 //check to see if this was already written out +1028 if (mp.getContextValue(this.getDataFileContextKey()) == null) { +1029 if (writeTo == null) { +1030 file = new File(mp.getBuild().getDirectory()); +1031 file = new File(file, dataFileName); +1032 } else { +1033 file = new File(writeTo, dataFileName); +1034 } +1035 final File parent = file.getParentFile(); +1036 if (!parent.isDirectory() && !parent.mkdirs()) { +1037 getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", +1038 parent.getAbsolutePath())); +1039 } +1040 +1041 ObjectOutputStream out = null; +1042 try { +1043 if (dependencies != null) { +1044 out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); +1045 out.writeObject(dependencies); +1046 } +1047 if (getLog().isDebugEnabled()) { +1048 getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s", +1049 file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey())); +1050 } +1051 mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath()); +1052 } catch (IOException ex) { +1053 getLog().warn("Unable to create data file used for report aggregation; " +1054 + "if report aggregation is being used the results may be incomplete."); +1055 if (getLog().isDebugEnabled()) { +1056 getLog().debug(ex.getMessage(), ex); +1057 } +1058 } finally { +1059 if (out != null) { +1060 try { +1061 out.close(); +1062 } catch (IOException ex) { +1063 if (getLog().isDebugEnabled()) { +1064 getLog().debug("ignore", ex); +1065 } +1066 } +1067 } +1068 } +1069 } +1070 } +1071 +1072 /** +1073 * Reads the serialized scan data from disk. This is used to serialize the +1074 * scan data between the "check" and "aggregate" phase. +1075 * +1076 * @param project the Maven project to read the data file from +1077 * @return a <code>Engine</code> object populated with dependencies if the +1078 * serialized data file exists; otherwise <code>null</code> is returned +1079 */ +1080 protected List<Dependency> readDataFile(MavenProject project) { +1081 final Object oPath = project.getContextValue(this.getDataFileContextKey()); +1082 if (oPath == null) { +1083 return null; +1084 } +1085 List<Dependency> ret = null; +1086 final String path = (String) oPath; +1087 //ObjectInputStream ois = null; +1088 ExpectedOjectInputStream ois = null; +1089 try { +1090 //ois = new ObjectInputStream(new FileInputStream(path)); +1091 ois = new ExpectedOjectInputStream(new FileInputStream(path), +1092 "java.util.ArrayList", +1093 "java.util.HashSet", +1094 "java.util.TreeSet", +1095 "java.lang.AbstractSet", +1096 "java.lang.AbstractCollection", +1097 "java.lang.Enum", +1098 "org.owasp.dependencycheck.dependency.Confidence", +1099 "org.owasp.dependencycheck.dependency.Dependency", +1100 "org.owasp.dependencycheck.dependency.Evidence", +1101 "org.owasp.dependencycheck.dependency.EvidenceCollection", +1102 "org.owasp.dependencycheck.dependency.Identifier", +1103 "org.owasp.dependencycheck.dependency.Reference", +1104 "org.owasp.dependencycheck.dependency.Vulnerability", +1105 "org.owasp.dependencycheck.dependency.VulnerabilityComparator", +1106 "org.owasp.dependencycheck.dependency.VulnerableSoftware", +1107 "org.owasp.dependencycheck.data.cpe.IndexEntry"); +1108 @SuppressWarnings("unchecked") +1109 final List<Dependency> depList = (List<Dependency>) ois.readObject(); +1110 ret = depList; +1111 } catch (FileNotFoundException ex) { +1112 //TODO fix logging +1113 getLog().error("", ex); +1114 } catch (IOException ex) { +1115 getLog().error("", ex); +1116 } catch (ClassNotFoundException ex) { +1117 getLog().error("", ex); +1118 } finally { +1119 if (ois != null) { +1120 try { +1121 ois.close(); +1122 } catch (IOException ex) { +1123 getLog().error("", ex); +1124 } +1125 } +1126 } +1127 return ret; +1128 } +1129 //</editor-fold> +1130 }
      diff --git a/xref/org/owasp/dependencycheck/maven/package-frame.html b/xref/org/owasp/dependencycheck/maven/package-frame.html index f4ce4dacd..65d71d367 100644 --- a/xref/org/owasp/dependencycheck/maven/package-frame.html +++ b/xref/org/owasp/dependencycheck/maven/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.maven + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven diff --git a/xref/org/owasp/dependencycheck/maven/package-summary.html b/xref/org/owasp/dependencycheck/maven/package-summary.html index 8d3b0c9b1..4f8be274f 100644 --- a/xref/org/owasp/dependencycheck/maven/package-summary.html +++ b/xref/org/owasp/dependencycheck/maven/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.maven + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven diff --git a/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html b/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html index 13a390452..f1f621aea 100644 --- a/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html +++ b/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.maven.slf4j + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven.slf4j diff --git a/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html b/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html index 3942a2a79..f3f081922 100644 --- a/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html +++ b/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.maven.slf4j + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven.slf4j diff --git a/xref/org/owasp/dependencycheck/package-frame.html b/xref/org/owasp/dependencycheck/package-frame.html index a783f5851..8b7202d7d 100644 --- a/xref/org/owasp/dependencycheck/package-frame.html +++ b/xref/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/xref/org/owasp/dependencycheck/package-summary.html b/xref/org/owasp/dependencycheck/package-summary.html index b39db5579..d591d92c8 100644 --- a/xref/org/owasp/dependencycheck/package-summary.html +++ b/xref/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck diff --git a/xref/org/owasp/dependencycheck/reporting/package-frame.html b/xref/org/owasp/dependencycheck/reporting/package-frame.html index a980a0f5a..68e26ec0a 100644 --- a/xref/org/owasp/dependencycheck/reporting/package-frame.html +++ b/xref/org/owasp/dependencycheck/reporting/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.reporting diff --git a/xref/org/owasp/dependencycheck/reporting/package-summary.html b/xref/org/owasp/dependencycheck/reporting/package-summary.html index 52d01d8c2..5705948b1 100644 --- a/xref/org/owasp/dependencycheck/reporting/package-summary.html +++ b/xref/org/owasp/dependencycheck/reporting/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.reporting diff --git a/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html b/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html index 506607034..366d09df7 100644 --- a/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html +++ b/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html @@ -55,87 +55,155 @@ 47 */ 48 private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class); 49 /** -50 * JAXP Schema Language. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html -51 */ -52 public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; -53 /** -54 * W3C XML Schema. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html -55 */ -56 public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; -57 /** -58 * JAXP Schema Source. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html -59 */ -60 public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; -61 -62 /** -63 * Parses the given xml file and returns a list of the suppression rules contained. -64 * -65 * @param file an xml file containing suppression rules -66 * @return a list of suppression rules -67 * @throws SuppressionParseException thrown if the xml file cannot be parsed -68 */ -69 public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException { -70 FileInputStream fis = null; -71 try { -72 fis = new FileInputStream(file); -73 return parseSuppressionRules(fis); -74 } catch (IOException ex) { -75 LOGGER.debug("", ex); -76 throw new SuppressionParseException(ex); -77 } finally { -78 if (fis != null) { -79 try { -80 fis.close(); -81 } catch (IOException ex) { -82 LOGGER.debug("Unable to close stream", ex); -83 } -84 } -85 } -86 } -87 -88 /** -89 * Parses the given xml stream and returns a list of the suppression rules contained. -90 * -91 * @param inputStream an InputStream containing suppression rues -92 * @return a list of suppression rules -93 * @throws SuppressionParseException if the xml cannot be parsed -94 */ -95 public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException { -96 try { -97 final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd"); -98 final SuppressionHandler handler = new SuppressionHandler(); -99 final SAXParserFactory factory = SAXParserFactory.newInstance(); -100 factory.setNamespaceAware(true); -101 factory.setValidating(true); -102 final SAXParser saxParser = factory.newSAXParser(); -103 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); -104 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream)); -105 final XMLReader xmlReader = saxParser.getXMLReader(); -106 xmlReader.setErrorHandler(new SuppressionErrorHandler()); -107 xmlReader.setContentHandler(handler); -108 -109 final Reader reader = new InputStreamReader(inputStream, "UTF-8"); -110 final InputSource in = new InputSource(reader); -111 //in.setEncoding("UTF-8"); -112 -113 xmlReader.parse(in); -114 -115 return handler.getSuppressionRules(); -116 } catch (ParserConfigurationException ex) { -117 LOGGER.debug("", ex); -118 throw new SuppressionParseException(ex); -119 } catch (SAXException ex) { -120 LOGGER.debug("", ex); -121 throw new SuppressionParseException(ex); -122 } catch (FileNotFoundException ex) { -123 LOGGER.debug("", ex); -124 throw new SuppressionParseException(ex); -125 } catch (IOException ex) { -126 LOGGER.debug("", ex); -127 throw new SuppressionParseException(ex); -128 } -129 } -130 } +50 * JAXP Schema Language. Source: +51 * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html +52 */ +53 public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; +54 /** +55 * W3C XML Schema. Source: +56 * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html +57 */ +58 public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; +59 /** +60 * JAXP Schema Source. Source: +61 * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html +62 */ +63 public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; +64 +65 /** +66 * Parses the given xml file and returns a list of the suppression rules +67 * contained. +68 * +69 * @param file an xml file containing suppression rules +70 * @return a list of suppression rules +71 * @throws SuppressionParseException thrown if the xml file cannot be parsed +72 */ +73 public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException { +74 FileInputStream fis = null; +75 try { +76 fis = new FileInputStream(file); +77 return parseSuppressionRules(fis); +78 } catch (IOException ex) { +79 LOGGER.debug("", ex); +80 throw new SuppressionParseException(ex); +81 } catch (SAXException ex) { +82 try { +83 if (fis != null) { +84 try { +85 fis.close(); +86 } catch (IOException ex1) { +87 LOGGER.debug("Unable to close stream", ex1); +88 } +89 } +90 fis = new FileInputStream(file); +91 } catch (FileNotFoundException ex1) { +92 throw new SuppressionParseException(ex); +93 } +94 return parseOldSuppressionRules(fis); +95 } finally { +96 if (fis != null) { +97 try { +98 fis.close(); +99 } catch (IOException ex) { +100 LOGGER.debug("Unable to close stream", ex); +101 } +102 } +103 } +104 } +105 +106 /** +107 * Parses the given xml stream and returns a list of the suppression rules +108 * contained. +109 * +110 * @param inputStream an InputStream containing suppression rues +111 * @return a list of suppression rules +112 * @throws SuppressionParseException thrown if the xml cannot be parsed +113 * @throws SAXException thrown if the xml cannot be parsed +114 */ +115 public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException { +116 try { +117 final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/dependency-suppression.1.1.xsd"); +118 final SuppressionHandler handler = new SuppressionHandler(); +119 final SAXParserFactory factory = SAXParserFactory.newInstance(); +120 factory.setNamespaceAware(true); +121 factory.setValidating(true); +122 final SAXParser saxParser = factory.newSAXParser(); +123 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); +124 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream)); +125 final XMLReader xmlReader = saxParser.getXMLReader(); +126 xmlReader.setErrorHandler(new SuppressionErrorHandler()); +127 xmlReader.setContentHandler(handler); +128 +129 final Reader reader = new InputStreamReader(inputStream, "UTF-8"); +130 final InputSource in = new InputSource(reader); +131 //in.setEncoding("UTF-8"); +132 +133 xmlReader.parse(in); +134 +135 return handler.getSuppressionRules(); +136 } catch (ParserConfigurationException ex) { +137 LOGGER.debug("", ex); +138 throw new SuppressionParseException(ex); +139 } catch (SAXException ex) { +140 if (ex.getMessage().contains("Cannot find the declaration of element 'suppressions'.")) { +141 throw ex; +142 } else { +143 LOGGER.debug("", ex); +144 throw new SuppressionParseException(ex); +145 } +146 } catch (FileNotFoundException ex) { +147 LOGGER.debug("", ex); +148 throw new SuppressionParseException(ex); +149 } catch (IOException ex) { +150 LOGGER.debug("", ex); +151 throw new SuppressionParseException(ex); +152 } +153 } +154 +155 /** +156 * Parses the given xml stream and returns a list of the suppression rules +157 * contained. +158 * +159 * @param inputStream an InputStream containing suppression rues +160 * @return a list of suppression rules +161 * @throws SuppressionParseException if the xml cannot be parsed +162 */ +163 private List<SuppressionRule> parseOldSuppressionRules(InputStream inputStream) throws SuppressionParseException { +164 try { +165 final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd"); +166 final SuppressionHandler handler = new SuppressionHandler(); +167 final SAXParserFactory factory = SAXParserFactory.newInstance(); +168 factory.setNamespaceAware(true); +169 factory.setValidating(true); +170 final SAXParser saxParser = factory.newSAXParser(); +171 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); +172 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream)); +173 final XMLReader xmlReader = saxParser.getXMLReader(); +174 xmlReader.setErrorHandler(new SuppressionErrorHandler()); +175 xmlReader.setContentHandler(handler); +176 +177 final Reader reader = new InputStreamReader(inputStream, "UTF-8"); +178 final InputSource in = new InputSource(reader); +179 //in.setEncoding("UTF-8"); +180 +181 xmlReader.parse(in); +182 +183 return handler.getSuppressionRules(); +184 } catch (ParserConfigurationException ex) { +185 LOGGER.debug("", ex); +186 throw new SuppressionParseException(ex); +187 } catch (SAXException ex) { +188 LOGGER.debug("", ex); +189 throw new SuppressionParseException(ex); +190 } catch (FileNotFoundException ex) { +191 LOGGER.debug("", ex); +192 throw new SuppressionParseException(ex); +193 } catch (IOException ex) { +194 LOGGER.debug("", ex); +195 throw new SuppressionParseException(ex); +196 } +197 } +198 }
      diff --git a/xref/org/owasp/dependencycheck/suppression/package-frame.html b/xref/org/owasp/dependencycheck/suppression/package-frame.html index cca0fda9b..7d46a66ad 100644 --- a/xref/org/owasp/dependencycheck/suppression/package-frame.html +++ b/xref/org/owasp/dependencycheck/suppression/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.suppression diff --git a/xref/org/owasp/dependencycheck/suppression/package-summary.html b/xref/org/owasp/dependencycheck/suppression/package-summary.html index 09facf3fd..65891d693 100644 --- a/xref/org/owasp/dependencycheck/suppression/package-summary.html +++ b/xref/org/owasp/dependencycheck/suppression/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.suppression diff --git a/xref/org/owasp/dependencycheck/taskdefs/Check.html b/xref/org/owasp/dependencycheck/taskdefs/Check.html index 1a58af172..fabfdab3a 100644 --- a/xref/org/owasp/dependencycheck/taskdefs/Check.html +++ b/xref/org/owasp/dependencycheck/taskdefs/Check.html @@ -94,8 +94,8 @@ 86 } 87 88 /** -89 * Returns the path. If the path has not been initialized yet, this class is synchronized, and will instantiate the path -90 * object. +89 * Returns the path. If the path has not been initialized yet, this class is +90 * synchronized, and will instantiate the path object. 91 * 92 * @return the path 93 */ @@ -117,861 +117,898 @@ 109 } 110 111 /** -112 * Add a reference to a Path, FileSet, DirSet, or FileList defined elsewhere. -113 * -114 * @param r the reference to a path, fileset, dirset or filelist. -115 */ -116 public void setRefid(Reference r) { -117 if (path != null) { -118 throw new BuildException("Nested elements are not allowed when using the refid attribute."); -119 } -120 refid = r; -121 } -122 -123 /** -124 * If this is a reference, this method will add the referenced resource collection to the collection of paths. -125 * -126 * @throws BuildException if the reference is not to a resource collection -127 */ -128 private void dealWithReferences() throws BuildException { -129 if (isReference()) { -130 final Object o = refid.getReferencedObject(getProject()); -131 if (!(o instanceof ResourceCollection)) { -132 throw new BuildException("refid '" + refid.getRefId() -133 + "' does not refer to a resource collection."); -134 } -135 getPath().add((ResourceCollection) o); -136 } -137 } -138 // END COPY from org.apache.tools.ant.taskdefs -139 /** -140 * The application name for the report. -141 * -142 * @deprecated use projectName instead. -143 */ -144 @Deprecated -145 private String applicationName = null; -146 -147 /** -148 * Get the value of applicationName. -149 * -150 * @return the value of applicationName +112 * Add a reference to a Path, FileSet, DirSet, or FileList defined +113 * elsewhere. +114 * +115 * @param r the reference to a path, fileset, dirset or filelist. +116 */ +117 public void setRefid(Reference r) { +118 if (path != null) { +119 throw new BuildException("Nested elements are not allowed when using the refid attribute."); +120 } +121 refid = r; +122 } +123 +124 /** +125 * If this is a reference, this method will add the referenced resource +126 * collection to the collection of paths. +127 * +128 * @throws BuildException if the reference is not to a resource collection +129 */ +130 private void dealWithReferences() throws BuildException { +131 if (isReference()) { +132 final Object o = refid.getReferencedObject(getProject()); +133 if (!(o instanceof ResourceCollection)) { +134 throw new BuildException("refid '" + refid.getRefId() +135 + "' does not refer to a resource collection."); +136 } +137 getPath().add((ResourceCollection) o); +138 } +139 } +140 // END COPY from org.apache.tools.ant.taskdefs +141 /** +142 * The application name for the report. +143 * +144 * @deprecated use projectName instead. +145 */ +146 @Deprecated +147 private String applicationName = null; +148 +149 /** +150 * Get the value of applicationName. 151 * -152 * @deprecated use projectName instead. -153 */ -154 @Deprecated -155 public String getApplicationName() { -156 return applicationName; -157 } -158 -159 /** -160 * Set the value of applicationName. -161 * -162 * @param applicationName new value of applicationName -163 * @deprecated use projectName instead. -164 */ -165 @Deprecated -166 public void setApplicationName(String applicationName) { -167 this.applicationName = applicationName; -168 } -169 /** -170 * The name of the project being analyzed. -171 */ -172 private String projectName = "dependency-check"; -173 -174 /** -175 * Get the value of projectName. -176 * -177 * @return the value of projectName -178 */ -179 public String getProjectName() { -180 if (applicationName != null) { -181 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN); -182 if ("dependency-check".equals(projectName)) { -183 projectName = applicationName; -184 } -185 } -186 return projectName; -187 } -188 -189 /** -190 * Set the value of projectName. -191 * -192 * @param projectName new value of projectName -193 */ -194 public void setProjectName(String projectName) { -195 this.projectName = projectName; -196 } -197 -198 /** -199 * Specifies the destination directory for the generated Dependency-Check report. -200 */ -201 private String reportOutputDirectory = "."; -202 -203 /** -204 * Get the value of reportOutputDirectory. -205 * -206 * @return the value of reportOutputDirectory -207 */ -208 public String getReportOutputDirectory() { -209 return reportOutputDirectory; -210 } -211 -212 /** -213 * Set the value of reportOutputDirectory. -214 * -215 * @param reportOutputDirectory new value of reportOutputDirectory -216 */ -217 public void setReportOutputDirectory(String reportOutputDirectory) { -218 this.reportOutputDirectory = reportOutputDirectory; -219 } -220 /** -221 * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which -222 * means since the CVSS scores are 0-10, by default the build will never fail and the CVSS score is set to 11. The valid range -223 * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail. -224 */ -225 private float failBuildOnCVSS = 11; -226 -227 /** -228 * Get the value of failBuildOnCVSS. -229 * -230 * @return the value of failBuildOnCVSS -231 */ -232 public float getFailBuildOnCVSS() { -233 return failBuildOnCVSS; -234 } -235 -236 /** -237 * Set the value of failBuildOnCVSS. -238 * -239 * @param failBuildOnCVSS new value of failBuildOnCVSS -240 */ -241 public void setFailBuildOnCVSS(float failBuildOnCVSS) { -242 this.failBuildOnCVSS = failBuildOnCVSS; -243 } -244 /** -245 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default -246 * is true. -247 */ -248 private Boolean autoUpdate; -249 -250 /** -251 * Get the value of autoUpdate. -252 * -253 * @return the value of autoUpdate -254 */ -255 public Boolean isAutoUpdate() { -256 return autoUpdate; -257 } -258 -259 /** -260 * Set the value of autoUpdate. -261 * -262 * @param autoUpdate new value of autoUpdate -263 */ -264 public void setAutoUpdate(Boolean autoUpdate) { -265 this.autoUpdate = autoUpdate; -266 } -267 /** -268 * Whether only the update phase should be executed. -269 * -270 * @deprecated Use the update task instead -271 */ -272 @Deprecated -273 private boolean updateOnly = false; -274 -275 /** -276 * Get the value of updateOnly. -277 * -278 * @return the value of updateOnly -279 * @deprecated Use the update task instead -280 */ -281 @Deprecated -282 public boolean isUpdateOnly() { -283 return updateOnly; -284 } -285 -286 /** -287 * Set the value of updateOnly. -288 * -289 * @param updateOnly new value of updateOnly -290 * @deprecated Use the update task instead -291 */ -292 @Deprecated -293 public void setUpdateOnly(boolean updateOnly) { -294 this.updateOnly = updateOnly; -295 } -296 -297 /** -298 * The report format to be generated (HTML, XML, VULN, ALL). Default is HTML. -299 */ -300 private String reportFormat = "HTML"; +152 * @return the value of applicationName +153 * +154 * @deprecated use projectName instead. +155 */ +156 @Deprecated +157 public String getApplicationName() { +158 return applicationName; +159 } +160 +161 /** +162 * Set the value of applicationName. +163 * +164 * @param applicationName new value of applicationName +165 * @deprecated use projectName instead. +166 */ +167 @Deprecated +168 public void setApplicationName(String applicationName) { +169 this.applicationName = applicationName; +170 } +171 /** +172 * The name of the project being analyzed. +173 */ +174 private String projectName = "dependency-check"; +175 +176 /** +177 * Get the value of projectName. +178 * +179 * @return the value of projectName +180 */ +181 public String getProjectName() { +182 if (applicationName != null) { +183 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN); +184 if ("dependency-check".equals(projectName)) { +185 projectName = applicationName; +186 } +187 } +188 return projectName; +189 } +190 +191 /** +192 * Set the value of projectName. +193 * +194 * @param projectName new value of projectName +195 */ +196 public void setProjectName(String projectName) { +197 this.projectName = projectName; +198 } +199 +200 /** +201 * Specifies the destination directory for the generated Dependency-Check +202 * report. +203 */ +204 private String reportOutputDirectory = "."; +205 +206 /** +207 * Get the value of reportOutputDirectory. +208 * +209 * @return the value of reportOutputDirectory +210 */ +211 public String getReportOutputDirectory() { +212 return reportOutputDirectory; +213 } +214 +215 /** +216 * Set the value of reportOutputDirectory. +217 * +218 * @param reportOutputDirectory new value of reportOutputDirectory +219 */ +220 public void setReportOutputDirectory(String reportOutputDirectory) { +221 this.reportOutputDirectory = reportOutputDirectory; +222 } +223 /** +224 * Specifies if the build should be failed if a CVSS score above a specified +225 * level is identified. The default is 11 which means since the CVSS scores +226 * are 0-10, by default the build will never fail and the CVSS score is set +227 * to 11. The valid range for the fail build on CVSS is 0 to 11, where +228 * anything above 10 will not cause the build to fail. +229 */ +230 private float failBuildOnCVSS = 11; +231 +232 /** +233 * Get the value of failBuildOnCVSS. +234 * +235 * @return the value of failBuildOnCVSS +236 */ +237 public float getFailBuildOnCVSS() { +238 return failBuildOnCVSS; +239 } +240 +241 /** +242 * Set the value of failBuildOnCVSS. +243 * +244 * @param failBuildOnCVSS new value of failBuildOnCVSS +245 */ +246 public void setFailBuildOnCVSS(float failBuildOnCVSS) { +247 this.failBuildOnCVSS = failBuildOnCVSS; +248 } +249 /** +250 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +251 * recommended that this be turned to false. Default is true. +252 */ +253 private Boolean autoUpdate; +254 +255 /** +256 * Get the value of autoUpdate. +257 * +258 * @return the value of autoUpdate +259 */ +260 public Boolean isAutoUpdate() { +261 return autoUpdate; +262 } +263 +264 /** +265 * Set the value of autoUpdate. +266 * +267 * @param autoUpdate new value of autoUpdate +268 */ +269 public void setAutoUpdate(Boolean autoUpdate) { +270 this.autoUpdate = autoUpdate; +271 } +272 /** +273 * Whether only the update phase should be executed. +274 * +275 * @deprecated Use the update task instead +276 */ +277 @Deprecated +278 private boolean updateOnly = false; +279 +280 /** +281 * Get the value of updateOnly. +282 * +283 * @return the value of updateOnly +284 * @deprecated Use the update task instead +285 */ +286 @Deprecated +287 public boolean isUpdateOnly() { +288 return updateOnly; +289 } +290 +291 /** +292 * Set the value of updateOnly. +293 * +294 * @param updateOnly new value of updateOnly +295 * @deprecated Use the update task instead +296 */ +297 @Deprecated +298 public void setUpdateOnly(boolean updateOnly) { +299 this.updateOnly = updateOnly; +300 } 301 302 /** -303 * Get the value of reportFormat. -304 * -305 * @return the value of reportFormat -306 */ -307 public String getReportFormat() { -308 return reportFormat; -309 } -310 -311 /** -312 * Set the value of reportFormat. -313 * -314 * @param reportFormat new value of reportFormat -315 */ -316 public void setReportFormat(ReportFormats reportFormat) { -317 this.reportFormat = reportFormat.getValue(); -318 } -319 /** -320 * The path to the suppression file. +303 * The report format to be generated (HTML, XML, VULN, ALL). Default is +304 * HTML. +305 */ +306 private String reportFormat = "HTML"; +307 +308 /** +309 * Get the value of reportFormat. +310 * +311 * @return the value of reportFormat +312 */ +313 public String getReportFormat() { +314 return reportFormat; +315 } +316 +317 /** +318 * Set the value of reportFormat. +319 * +320 * @param reportFormat new value of reportFormat 321 */ -322 private String suppressionFile; -323 -324 /** -325 * Get the value of suppressionFile. -326 * -327 * @return the value of suppressionFile -328 */ -329 public String getSuppressionFile() { -330 return suppressionFile; -331 } -332 -333 /** -334 * Set the value of suppressionFile. -335 * -336 * @param suppressionFile new value of suppressionFile -337 */ -338 public void setSuppressionFile(String suppressionFile) { -339 this.suppressionFile = suppressionFile; -340 } -341 /** -342 * flag indicating whether or not to show a summary of findings. +322 public void setReportFormat(ReportFormats reportFormat) { +323 this.reportFormat = reportFormat.getValue(); +324 } +325 /** +326 * The path to the suppression file. +327 */ +328 private String suppressionFile; +329 +330 /** +331 * Get the value of suppressionFile. +332 * +333 * @return the value of suppressionFile +334 */ +335 public String getSuppressionFile() { +336 return suppressionFile; +337 } +338 +339 /** +340 * Set the value of suppressionFile. +341 * +342 * @param suppressionFile new value of suppressionFile 343 */ -344 private boolean showSummary = true; -345 -346 /** -347 * Get the value of showSummary. -348 * -349 * @return the value of showSummary -350 */ -351 public boolean isShowSummary() { -352 return showSummary; -353 } -354 -355 /** -356 * Set the value of showSummary. -357 * -358 * @param showSummary new value of showSummary -359 */ -360 public void setShowSummary(boolean showSummary) { -361 this.showSummary = showSummary; -362 } -363 -364 /** -365 * Whether or not the Jar Analyzer is enabled. -366 */ -367 private Boolean jarAnalyzerEnabled; -368 -369 /** -370 * Returns whether or not the analyzer is enabled. -371 * -372 * @return true if the analyzer is enabled -373 */ -374 public Boolean isJarAnalyzerEnabled() { -375 return jarAnalyzerEnabled; -376 } -377 -378 /** -379 * Sets whether or not the analyzer is enabled. -380 * -381 * @param jarAnalyzerEnabled the value of the new setting -382 */ -383 public void setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) { -384 this.jarAnalyzerEnabled = jarAnalyzerEnabled; -385 } -386 /** -387 * Whether or not the Archive Analyzer is enabled. +344 public void setSuppressionFile(String suppressionFile) { +345 this.suppressionFile = suppressionFile; +346 } +347 /** +348 * flag indicating whether or not to show a summary of findings. +349 */ +350 private boolean showSummary = true; +351 +352 /** +353 * Get the value of showSummary. +354 * +355 * @return the value of showSummary +356 */ +357 public boolean isShowSummary() { +358 return showSummary; +359 } +360 +361 /** +362 * Set the value of showSummary. +363 * +364 * @param showSummary new value of showSummary +365 */ +366 public void setShowSummary(boolean showSummary) { +367 this.showSummary = showSummary; +368 } +369 +370 /** +371 * Whether experimental analyzers are enabled. +372 */ +373 private Boolean enableExperimental; +374 +375 /** +376 * Get the value of enableExperimental. +377 * +378 * @return the value of enableExperimental +379 */ +380 public Boolean isEnableExperimental() { +381 return enableExperimental; +382 } +383 +384 /** +385 * Set the value of enableExperimental. +386 * +387 * @param enableExperimental new value of enableExperimental 388 */ -389 private Boolean archiveAnalyzerEnabled; -390 -391 /** -392 * Returns whether or not the analyzer is enabled. -393 * -394 * @return true if the analyzer is enabled +389 public void setEnableExperimental(Boolean enableExperimental) { +390 this.enableExperimental = enableExperimental; +391 } +392 +393 /** +394 * Whether or not the Jar Analyzer is enabled. 395 */ -396 public Boolean isArchiveAnalyzerEnabled() { -397 return archiveAnalyzerEnabled; -398 } -399 /** -400 * Whether or not the .NET Assembly Analyzer is enabled. -401 */ -402 private Boolean assemblyAnalyzerEnabled; -403 -404 /** -405 * Sets whether or not the analyzer is enabled. -406 * -407 * @param archiveAnalyzerEnabled the value of the new setting -408 */ -409 public void setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) { -410 this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; -411 } -412 -413 /** -414 * Returns whether or not the analyzer is enabled. -415 * -416 * @return true if the analyzer is enabled +396 private Boolean jarAnalyzerEnabled; +397 +398 /** +399 * Returns whether or not the analyzer is enabled. +400 * +401 * @return true if the analyzer is enabled +402 */ +403 public Boolean isJarAnalyzerEnabled() { +404 return jarAnalyzerEnabled; +405 } +406 +407 /** +408 * Sets whether or not the analyzer is enabled. +409 * +410 * @param jarAnalyzerEnabled the value of the new setting +411 */ +412 public void setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) { +413 this.jarAnalyzerEnabled = jarAnalyzerEnabled; +414 } +415 /** +416 * Whether or not the Archive Analyzer is enabled. 417 */ -418 public Boolean isAssemblyAnalyzerEnabled() { -419 return assemblyAnalyzerEnabled; -420 } -421 -422 /** -423 * Sets whether or not the analyzer is enabled. -424 * -425 * @param assemblyAnalyzerEnabled the value of the new setting -426 */ -427 public void setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) { -428 this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; -429 } -430 /** -431 * Whether or not the .NET Nuspec Analyzer is enabled. -432 */ -433 private Boolean nuspecAnalyzerEnabled; -434 -435 /** -436 * Returns whether or not the analyzer is enabled. -437 * -438 * @return true if the analyzer is enabled -439 */ -440 public Boolean isNuspecAnalyzerEnabled() { -441 return nuspecAnalyzerEnabled; -442 } -443 -444 /** -445 * Sets whether or not the analyzer is enabled. -446 * -447 * @param nuspecAnalyzerEnabled the value of the new setting -448 */ -449 public void setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) { -450 this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; -451 } -452 /** -453 * Whether or not the PHP Composer Analyzer is enabled. -454 */ -455 private Boolean composerAnalyzerEnabled; -456 -457 /** -458 * Get the value of composerAnalyzerEnabled. -459 * -460 * @return the value of composerAnalyzerEnabled +418 private Boolean archiveAnalyzerEnabled; +419 +420 /** +421 * Returns whether or not the analyzer is enabled. +422 * +423 * @return true if the analyzer is enabled +424 */ +425 public Boolean isArchiveAnalyzerEnabled() { +426 return archiveAnalyzerEnabled; +427 } +428 /** +429 * Whether or not the .NET Assembly Analyzer is enabled. +430 */ +431 private Boolean assemblyAnalyzerEnabled; +432 +433 /** +434 * Sets whether or not the analyzer is enabled. +435 * +436 * @param archiveAnalyzerEnabled the value of the new setting +437 */ +438 public void setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) { +439 this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; +440 } +441 +442 /** +443 * Returns whether or not the analyzer is enabled. +444 * +445 * @return true if the analyzer is enabled +446 */ +447 public Boolean isAssemblyAnalyzerEnabled() { +448 return assemblyAnalyzerEnabled; +449 } +450 +451 /** +452 * Sets whether or not the analyzer is enabled. +453 * +454 * @param assemblyAnalyzerEnabled the value of the new setting +455 */ +456 public void setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) { +457 this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; +458 } +459 /** +460 * Whether or not the .NET Nuspec Analyzer is enabled. 461 */ -462 public Boolean isComposerAnalyzerEnabled() { -463 return composerAnalyzerEnabled; -464 } -465 -466 /** -467 * Set the value of composerAnalyzerEnabled. -468 * -469 * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled -470 */ -471 public void setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) { -472 this.composerAnalyzerEnabled = composerAnalyzerEnabled; -473 } -474 /** -475 * Whether the autoconf analyzer should be enabled. -476 */ -477 private Boolean autoconfAnalyzerEnabled; -478 -479 /** -480 * Get the value of autoconfAnalyzerEnabled. -481 * -482 * @return the value of autoconfAnalyzerEnabled +462 private Boolean nuspecAnalyzerEnabled; +463 +464 /** +465 * Returns whether or not the analyzer is enabled. +466 * +467 * @return true if the analyzer is enabled +468 */ +469 public Boolean isNuspecAnalyzerEnabled() { +470 return nuspecAnalyzerEnabled; +471 } +472 +473 /** +474 * Sets whether or not the analyzer is enabled. +475 * +476 * @param nuspecAnalyzerEnabled the value of the new setting +477 */ +478 public void setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) { +479 this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; +480 } +481 /** +482 * Whether or not the PHP Composer Analyzer is enabled. 483 */ -484 public Boolean isAutoconfAnalyzerEnabled() { -485 return autoconfAnalyzerEnabled; -486 } -487 -488 /** -489 * Set the value of autoconfAnalyzerEnabled. -490 * -491 * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled -492 */ -493 public void setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) { -494 this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled; -495 } -496 /** -497 * Whether the CMake analyzer should be enabled. -498 */ -499 private Boolean cmakeAnalyzerEnabled; -500 -501 /** -502 * Get the value of cmakeAnalyzerEnabled. -503 * -504 * @return the value of cmakeAnalyzerEnabled +484 private Boolean composerAnalyzerEnabled; +485 +486 /** +487 * Get the value of composerAnalyzerEnabled. +488 * +489 * @return the value of composerAnalyzerEnabled +490 */ +491 public Boolean isComposerAnalyzerEnabled() { +492 return composerAnalyzerEnabled; +493 } +494 +495 /** +496 * Set the value of composerAnalyzerEnabled. +497 * +498 * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled +499 */ +500 public void setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) { +501 this.composerAnalyzerEnabled = composerAnalyzerEnabled; +502 } +503 /** +504 * Whether the autoconf analyzer should be enabled. 505 */ -506 public Boolean isCMakeAnalyzerEnabled() { -507 return cmakeAnalyzerEnabled; -508 } -509 -510 /** -511 * Set the value of cmakeAnalyzerEnabled. -512 * -513 * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled -514 */ -515 public void setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) { -516 this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled; -517 } -518 /** -519 * Whether or not the openssl analyzer is enabled. -520 */ -521 private Boolean opensslAnalyzerEnabled; -522 -523 /** -524 * Get the value of opensslAnalyzerEnabled. -525 * -526 * @return the value of opensslAnalyzerEnabled +506 private Boolean autoconfAnalyzerEnabled; +507 +508 /** +509 * Get the value of autoconfAnalyzerEnabled. +510 * +511 * @return the value of autoconfAnalyzerEnabled +512 */ +513 public Boolean isAutoconfAnalyzerEnabled() { +514 return autoconfAnalyzerEnabled; +515 } +516 +517 /** +518 * Set the value of autoconfAnalyzerEnabled. +519 * +520 * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled +521 */ +522 public void setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) { +523 this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled; +524 } +525 /** +526 * Whether the CMake analyzer should be enabled. 527 */ -528 public Boolean isOpensslAnalyzerEnabled() { -529 return opensslAnalyzerEnabled; -530 } -531 -532 /** -533 * Set the value of opensslAnalyzerEnabled. -534 * -535 * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled -536 */ -537 public void setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) { -538 this.opensslAnalyzerEnabled = opensslAnalyzerEnabled; -539 } -540 /** -541 * Whether or not the Node.js Analyzer is enabled. -542 */ -543 private Boolean nodeAnalyzerEnabled; -544 -545 /** -546 * Get the value of nodeAnalyzerEnabled. -547 * -548 * @return the value of nodeAnalyzerEnabled +528 private Boolean cmakeAnalyzerEnabled; +529 +530 /** +531 * Get the value of cmakeAnalyzerEnabled. +532 * +533 * @return the value of cmakeAnalyzerEnabled +534 */ +535 public Boolean isCMakeAnalyzerEnabled() { +536 return cmakeAnalyzerEnabled; +537 } +538 +539 /** +540 * Set the value of cmakeAnalyzerEnabled. +541 * +542 * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled +543 */ +544 public void setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) { +545 this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled; +546 } +547 /** +548 * Whether or not the openssl analyzer is enabled. 549 */ -550 public Boolean isNodeAnalyzerEnabled() { -551 return nodeAnalyzerEnabled; -552 } -553 -554 /** -555 * Set the value of nodeAnalyzerEnabled. -556 * -557 * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled -558 */ -559 public void setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) { -560 this.nodeAnalyzerEnabled = nodeAnalyzerEnabled; -561 } -562 /** -563 * Whether the ruby gemspec analyzer should be enabled. -564 */ -565 private Boolean rubygemsAnalyzerEnabled; -566 -567 /** -568 * Get the value of rubygemsAnalyzerEnabled. -569 * -570 * @return the value of rubygemsAnalyzerEnabled +550 private Boolean opensslAnalyzerEnabled; +551 +552 /** +553 * Get the value of opensslAnalyzerEnabled. +554 * +555 * @return the value of opensslAnalyzerEnabled +556 */ +557 public Boolean isOpensslAnalyzerEnabled() { +558 return opensslAnalyzerEnabled; +559 } +560 +561 /** +562 * Set the value of opensslAnalyzerEnabled. +563 * +564 * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled +565 */ +566 public void setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) { +567 this.opensslAnalyzerEnabled = opensslAnalyzerEnabled; +568 } +569 /** +570 * Whether or not the Node.js Analyzer is enabled. 571 */ -572 public Boolean isRubygemsAnalyzerEnabled() { -573 return rubygemsAnalyzerEnabled; -574 } -575 -576 /** -577 * Set the value of rubygemsAnalyzerEnabled. -578 * -579 * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled -580 */ -581 public void setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) { -582 this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled; -583 } -584 /** -585 * Whether the python package analyzer should be enabled. -586 */ -587 private Boolean pyPackageAnalyzerEnabled; -588 -589 /** -590 * Get the value of pyPackageAnalyzerEnabled. -591 * -592 * @return the value of pyPackageAnalyzerEnabled +572 private Boolean nodeAnalyzerEnabled; +573 +574 /** +575 * Get the value of nodeAnalyzerEnabled. +576 * +577 * @return the value of nodeAnalyzerEnabled +578 */ +579 public Boolean isNodeAnalyzerEnabled() { +580 return nodeAnalyzerEnabled; +581 } +582 +583 /** +584 * Set the value of nodeAnalyzerEnabled. +585 * +586 * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled +587 */ +588 public void setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) { +589 this.nodeAnalyzerEnabled = nodeAnalyzerEnabled; +590 } +591 /** +592 * Whether the ruby gemspec analyzer should be enabled. 593 */ -594 public Boolean isPyPackageAnalyzerEnabled() { -595 return pyPackageAnalyzerEnabled; -596 } -597 -598 /** -599 * Set the value of pyPackageAnalyzerEnabled. -600 * -601 * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled -602 */ -603 public void setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) { -604 this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled; -605 } -606 -607 /** -608 * Whether the python distribution analyzer should be enabled. +594 private Boolean rubygemsAnalyzerEnabled; +595 +596 /** +597 * Get the value of rubygemsAnalyzerEnabled. +598 * +599 * @return the value of rubygemsAnalyzerEnabled +600 */ +601 public Boolean isRubygemsAnalyzerEnabled() { +602 return rubygemsAnalyzerEnabled; +603 } +604 +605 /** +606 * Set the value of rubygemsAnalyzerEnabled. +607 * +608 * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled 609 */ -610 private Boolean pyDistributionAnalyzerEnabled; -611 -612 /** -613 * Get the value of pyDistributionAnalyzerEnabled. -614 * -615 * @return the value of pyDistributionAnalyzerEnabled -616 */ -617 public Boolean isPyDistributionAnalyzerEnabled() { -618 return pyDistributionAnalyzerEnabled; -619 } -620 -621 /** -622 * Set the value of pyDistributionAnalyzerEnabled. -623 * -624 * @param pyDistributionAnalyzerEnabled new value of pyDistributionAnalyzerEnabled -625 */ -626 public void setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { -627 this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; -628 } -629 -630 /** -631 * Whether or not the central analyzer is enabled. -632 */ -633 private Boolean centralAnalyzerEnabled; -634 -635 /** -636 * Get the value of centralAnalyzerEnabled. -637 * -638 * @return the value of centralAnalyzerEnabled -639 */ -640 public Boolean isCentralAnalyzerEnabled() { -641 return centralAnalyzerEnabled; -642 } -643 -644 /** -645 * Set the value of centralAnalyzerEnabled. -646 * -647 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled -648 */ -649 public void setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) { -650 this.centralAnalyzerEnabled = centralAnalyzerEnabled; -651 } -652 -653 /** -654 * Whether or not the nexus analyzer is enabled. +610 public void setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) { +611 this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled; +612 } +613 /** +614 * Whether the python package analyzer should be enabled. +615 */ +616 private Boolean pyPackageAnalyzerEnabled; +617 +618 /** +619 * Get the value of pyPackageAnalyzerEnabled. +620 * +621 * @return the value of pyPackageAnalyzerEnabled +622 */ +623 public Boolean isPyPackageAnalyzerEnabled() { +624 return pyPackageAnalyzerEnabled; +625 } +626 +627 /** +628 * Set the value of pyPackageAnalyzerEnabled. +629 * +630 * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled +631 */ +632 public void setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) { +633 this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled; +634 } +635 +636 /** +637 * Whether the python distribution analyzer should be enabled. +638 */ +639 private Boolean pyDistributionAnalyzerEnabled; +640 +641 /** +642 * Get the value of pyDistributionAnalyzerEnabled. +643 * +644 * @return the value of pyDistributionAnalyzerEnabled +645 */ +646 public Boolean isPyDistributionAnalyzerEnabled() { +647 return pyDistributionAnalyzerEnabled; +648 } +649 +650 /** +651 * Set the value of pyDistributionAnalyzerEnabled. +652 * +653 * @param pyDistributionAnalyzerEnabled new value of +654 * pyDistributionAnalyzerEnabled 655 */ -656 private Boolean nexusAnalyzerEnabled; -657 -658 /** -659 * Get the value of nexusAnalyzerEnabled. -660 * -661 * @return the value of nexusAnalyzerEnabled +656 public void setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { +657 this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; +658 } +659 +660 /** +661 * Whether or not the central analyzer is enabled. 662 */ -663 public Boolean isNexusAnalyzerEnabled() { -664 return nexusAnalyzerEnabled; -665 } -666 -667 /** -668 * Set the value of nexusAnalyzerEnabled. -669 * -670 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled -671 */ -672 public void setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) { -673 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; -674 } -675 -676 /** -677 * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local). +663 private Boolean centralAnalyzerEnabled; +664 +665 /** +666 * Get the value of centralAnalyzerEnabled. +667 * +668 * @return the value of centralAnalyzerEnabled +669 */ +670 public Boolean isCentralAnalyzerEnabled() { +671 return centralAnalyzerEnabled; +672 } +673 +674 /** +675 * Set the value of centralAnalyzerEnabled. +676 * +677 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled 678 */ -679 private String nexusUrl; -680 -681 /** -682 * Get the value of nexusUrl. -683 * -684 * @return the value of nexusUrl +679 public void setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) { +680 this.centralAnalyzerEnabled = centralAnalyzerEnabled; +681 } +682 +683 /** +684 * Whether or not the nexus analyzer is enabled. 685 */ -686 public String getNexusUrl() { -687 return nexusUrl; -688 } -689 -690 /** -691 * Set the value of nexusUrl. -692 * -693 * @param nexusUrl new value of nexusUrl -694 */ -695 public void setNexusUrl(String nexusUrl) { -696 this.nexusUrl = nexusUrl; -697 } -698 /** -699 * Whether or not the defined proxy should be used when connecting to Nexus. -700 */ -701 private Boolean nexusUsesProxy; -702 -703 /** -704 * Get the value of nexusUsesProxy. -705 * -706 * @return the value of nexusUsesProxy -707 */ -708 public Boolean isNexusUsesProxy() { -709 return nexusUsesProxy; -710 } +686 private Boolean nexusAnalyzerEnabled; +687 +688 /** +689 * Get the value of nexusAnalyzerEnabled. +690 * +691 * @return the value of nexusAnalyzerEnabled +692 */ +693 public Boolean isNexusAnalyzerEnabled() { +694 return nexusAnalyzerEnabled; +695 } +696 +697 /** +698 * Set the value of nexusAnalyzerEnabled. +699 * +700 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled +701 */ +702 public void setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) { +703 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; +704 } +705 +706 /** +707 * The URL of a Nexus server's REST API end point +708 * (http://domain/nexus/service/local). +709 */ +710 private String nexusUrl; 711 712 /** -713 * Set the value of nexusUsesProxy. +713 * Get the value of nexusUrl. 714 * -715 * @param nexusUsesProxy new value of nexusUsesProxy +715 * @return the value of nexusUrl 716 */ -717 public void setNexusUsesProxy(Boolean nexusUsesProxy) { -718 this.nexusUsesProxy = nexusUsesProxy; +717 public String getNexusUrl() { +718 return nexusUrl; 719 } 720 721 /** -722 * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP -723 * files. -724 */ -725 private String zipExtensions; -726 -727 /** -728 * Get the value of zipExtensions. -729 * -730 * @return the value of zipExtensions +722 * Set the value of nexusUrl. +723 * +724 * @param nexusUrl new value of nexusUrl +725 */ +726 public void setNexusUrl(String nexusUrl) { +727 this.nexusUrl = nexusUrl; +728 } +729 /** +730 * Whether or not the defined proxy should be used when connecting to Nexus. 731 */ -732 public String getZipExtensions() { -733 return zipExtensions; -734 } -735 -736 /** -737 * Set the value of zipExtensions. -738 * -739 * @param zipExtensions new value of zipExtensions -740 */ -741 public void setZipExtensions(String zipExtensions) { -742 this.zipExtensions = zipExtensions; -743 } -744 -745 /** -746 * The path to Mono for .NET assembly analysis on non-windows systems. +732 private Boolean nexusUsesProxy; +733 +734 /** +735 * Get the value of nexusUsesProxy. +736 * +737 * @return the value of nexusUsesProxy +738 */ +739 public Boolean isNexusUsesProxy() { +740 return nexusUsesProxy; +741 } +742 +743 /** +744 * Set the value of nexusUsesProxy. +745 * +746 * @param nexusUsesProxy new value of nexusUsesProxy 747 */ -748 private String pathToMono; -749 -750 /** -751 * Get the value of pathToMono. -752 * -753 * @return the value of pathToMono -754 */ -755 public String getPathToMono() { -756 return pathToMono; -757 } -758 -759 /** -760 * Set the value of pathToMono. -761 * -762 * @param pathToMono new value of pathToMono -763 */ -764 public void setPathToMono(String pathToMono) { -765 this.pathToMono = pathToMono; -766 } -767 -768 @Override -769 public void execute() throws BuildException { -770 dealWithReferences(); -771 validateConfiguration(); -772 populateSettings(); -773 Engine engine = null; -774 try { -775 engine = new Engine(Check.class.getClassLoader()); -776 if (isUpdateOnly()) { -777 log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN); -778 engine.doUpdates(); -779 } else { -780 try { -781 for (Resource resource : path) { -782 final FileProvider provider = resource.as(FileProvider.class); -783 if (provider != null) { -784 final File file = provider.getFile(); -785 if (file != null && file.exists()) { -786 engine.scan(file); -787 } -788 } -789 } -790 -791 engine.analyzeDependencies(); -792 DatabaseProperties prop = null; -793 CveDB cve = null; -794 try { -795 cve = new CveDB(); -796 cve.open(); -797 prop = cve.getDatabaseProperties(); -798 } catch (DatabaseException ex) { -799 log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); -800 } finally { -801 if (cve != null) { -802 cve.close(); -803 } -804 } -805 final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); -806 reporter.generateReports(reportOutputDirectory, reportFormat); -807 -808 if (this.failBuildOnCVSS <= 10) { -809 checkForFailure(engine.getDependencies()); -810 } -811 if (this.showSummary) { -812 showSummary(engine.getDependencies()); -813 } -814 } catch (IOException ex) { -815 log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG); -816 throw new BuildException("Unable to generate dependency-check report", ex); -817 } catch (Exception ex) { -818 log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG); -819 throw new BuildException("An exception occurred; unable to continue task", ex); -820 } -821 } -822 } catch (DatabaseException ex) { -823 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR); -824 } finally { -825 Settings.cleanup(true); -826 if (engine != null) { -827 engine.cleanup(); -828 } -829 } -830 } -831 -832 /** -833 * Validate the configuration to ensure the parameters have been properly configured/initialized. -834 * -835 * @throws BuildException if the task was not configured correctly. -836 */ -837 private void validateConfiguration() throws BuildException { -838 if (path == null) { -839 throw new BuildException("No project dependencies have been defined to analyze."); -840 } -841 if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { -842 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); -843 } -844 } -845 -846 /** -847 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -848 * required to change the proxy server, port, and connection timeout. -849 * -850 * @throws BuildException thrown when an invalid setting is configured. -851 */ -852 @Override -853 protected void populateSettings() throws BuildException { -854 super.populateSettings(); -855 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); -856 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -857 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); -858 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); -859 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); -860 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); -861 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); -862 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); -863 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); -864 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); -865 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); -866 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); -867 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -868 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -869 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); -870 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); -871 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -872 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -873 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -874 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -875 } -876 -877 /** -878 * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the -879 * configuration. -880 * -881 * @param dependencies the list of dependency objects -882 * @throws BuildException thrown if a CVSS score is found that is higher then the threshold set -883 */ -884 private void checkForFailure(List<Dependency> dependencies) throws BuildException { -885 final StringBuilder ids = new StringBuilder(); -886 for (Dependency d : dependencies) { -887 for (Vulnerability v : d.getVulnerabilities()) { -888 if (v.getCvssScore() >= failBuildOnCVSS) { -889 if (ids.length() == 0) { -890 ids.append(v.getName()); -891 } else { -892 ids.append(", ").append(v.getName()); -893 } -894 } -895 } -896 } -897 if (ids.length() > 0) { -898 final String msg = String.format("%n%nDependency-Check Failure:%n" -899 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -900 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -901 throw new BuildException(msg); -902 } -903 } -904 -905 /** -906 * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. -907 * -908 * @param dependencies a list of dependency objects -909 */ -910 private void showSummary(List<Dependency> dependencies) { -911 final StringBuilder summary = new StringBuilder(); -912 for (Dependency d : dependencies) { -913 boolean firstEntry = true; -914 final StringBuilder ids = new StringBuilder(); -915 for (Vulnerability v : d.getVulnerabilities()) { -916 if (firstEntry) { -917 firstEntry = false; -918 } else { -919 ids.append(", "); -920 } -921 ids.append(v.getName()); -922 } -923 if (ids.length() > 0) { -924 summary.append(d.getFileName()).append(" ("); -925 firstEntry = true; -926 for (Identifier id : d.getIdentifiers()) { -927 if (firstEntry) { -928 firstEntry = false; -929 } else { -930 summary.append(", "); -931 } -932 summary.append(id.getValue()); -933 } -934 summary.append(") : ").append(ids).append(NEW_LINE); -935 } -936 } -937 if (summary.length() > 0) { -938 final String msg = String.format("%n%n" -939 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" -940 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); -941 log(msg, Project.MSG_WARN); -942 } -943 } -944 -945 /** -946 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", etc.. -947 */ -948 public static class ReportFormats extends EnumeratedAttribute { -949 -950 /** -951 * Returns the list of values for the report format. -952 * -953 * @return the list of values for the report format -954 */ -955 @Override -956 public String[] getValues() { -957 int i = 0; -958 final Format[] formats = Format.values(); -959 final String[] values = new String[formats.length]; -960 for (Format format : formats) { -961 values[i++] = format.name(); -962 } -963 return values; -964 } -965 } -966 } +748 public void setNexusUsesProxy(Boolean nexusUsesProxy) { +749 this.nexusUsesProxy = nexusUsesProxy; +750 } +751 +752 /** +753 * Additional ZIP File extensions to add analyze. This should be a +754 * comma-separated list of file extensions to treat like ZIP files. +755 */ +756 private String zipExtensions; +757 +758 /** +759 * Get the value of zipExtensions. +760 * +761 * @return the value of zipExtensions +762 */ +763 public String getZipExtensions() { +764 return zipExtensions; +765 } +766 +767 /** +768 * Set the value of zipExtensions. +769 * +770 * @param zipExtensions new value of zipExtensions +771 */ +772 public void setZipExtensions(String zipExtensions) { +773 this.zipExtensions = zipExtensions; +774 } +775 +776 /** +777 * The path to Mono for .NET assembly analysis on non-windows systems. +778 */ +779 private String pathToMono; +780 +781 /** +782 * Get the value of pathToMono. +783 * +784 * @return the value of pathToMono +785 */ +786 public String getPathToMono() { +787 return pathToMono; +788 } +789 +790 /** +791 * Set the value of pathToMono. +792 * +793 * @param pathToMono new value of pathToMono +794 */ +795 public void setPathToMono(String pathToMono) { +796 this.pathToMono = pathToMono; +797 } +798 +799 @Override +800 public void execute() throws BuildException { +801 dealWithReferences(); +802 validateConfiguration(); +803 populateSettings(); +804 Engine engine = null; +805 try { +806 engine = new Engine(Check.class.getClassLoader()); +807 if (isUpdateOnly()) { +808 log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN); +809 engine.doUpdates(); +810 } else { +811 try { +812 for (Resource resource : path) { +813 final FileProvider provider = resource.as(FileProvider.class); +814 if (provider != null) { +815 final File file = provider.getFile(); +816 if (file != null && file.exists()) { +817 engine.scan(file); +818 } +819 } +820 } +821 +822 engine.analyzeDependencies(); +823 DatabaseProperties prop = null; +824 CveDB cve = null; +825 try { +826 cve = new CveDB(); +827 cve.open(); +828 prop = cve.getDatabaseProperties(); +829 } catch (DatabaseException ex) { +830 log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); +831 } finally { +832 if (cve != null) { +833 cve.close(); +834 } +835 } +836 final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); +837 reporter.generateReports(reportOutputDirectory, reportFormat); +838 +839 if (this.failBuildOnCVSS <= 10) { +840 checkForFailure(engine.getDependencies()); +841 } +842 if (this.showSummary) { +843 showSummary(engine.getDependencies()); +844 } +845 } catch (IOException ex) { +846 log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG); +847 throw new BuildException("Unable to generate dependency-check report", ex); +848 } catch (Exception ex) { +849 log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG); +850 throw new BuildException("An exception occurred; unable to continue task", ex); +851 } +852 } +853 } catch (DatabaseException ex) { +854 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR); +855 } finally { +856 Settings.cleanup(true); +857 if (engine != null) { +858 engine.cleanup(); +859 } +860 } +861 } +862 +863 /** +864 * Validate the configuration to ensure the parameters have been properly +865 * configured/initialized. +866 * +867 * @throws BuildException if the task was not configured correctly. +868 */ +869 private void validateConfiguration() throws BuildException { +870 if (path == null) { +871 throw new BuildException("No project dependencies have been defined to analyze."); +872 } +873 if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { +874 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); +875 } +876 } +877 +878 /** +879 * Takes the properties supplied and updates the dependency-check settings. +880 * Additionally, this sets the system properties required to change the +881 * proxy server, port, and connection timeout. +882 * +883 * @throws BuildException thrown when an invalid setting is configured. +884 */ +885 @Override +886 protected void populateSettings() throws BuildException { +887 super.populateSettings(); +888 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); +889 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +890 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); +891 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); +892 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); +893 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); +894 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); +895 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); +896 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); +897 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); +898 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); +899 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +900 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); +901 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +902 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +903 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); +904 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); +905 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +906 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +907 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +908 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +909 } +910 +911 /** +912 * Checks to see if a vulnerability has been identified with a CVSS score +913 * that is above the threshold set in the configuration. +914 * +915 * @param dependencies the list of dependency objects +916 * @throws BuildException thrown if a CVSS score is found that is higher +917 * then the threshold set +918 */ +919 private void checkForFailure(List<Dependency> dependencies) throws BuildException { +920 final StringBuilder ids = new StringBuilder(); +921 for (Dependency d : dependencies) { +922 for (Vulnerability v : d.getVulnerabilities()) { +923 if (v.getCvssScore() >= failBuildOnCVSS) { +924 if (ids.length() == 0) { +925 ids.append(v.getName()); +926 } else { +927 ids.append(", ").append(v.getName()); +928 } +929 } +930 } +931 } +932 if (ids.length() > 0) { +933 final String msg = String.format("%n%nDependency-Check Failure:%n" +934 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +935 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +936 throw new BuildException(msg); +937 } +938 } +939 +940 /** +941 * Generates a warning message listing a summary of dependencies and their +942 * associated CPE and CVE entries. +943 * +944 * @param dependencies a list of dependency objects +945 */ +946 private void showSummary(List<Dependency> dependencies) { +947 final StringBuilder summary = new StringBuilder(); +948 for (Dependency d : dependencies) { +949 boolean firstEntry = true; +950 final StringBuilder ids = new StringBuilder(); +951 for (Vulnerability v : d.getVulnerabilities()) { +952 if (firstEntry) { +953 firstEntry = false; +954 } else { +955 ids.append(", "); +956 } +957 ids.append(v.getName()); +958 } +959 if (ids.length() > 0) { +960 summary.append(d.getFileName()).append(" ("); +961 firstEntry = true; +962 for (Identifier id : d.getIdentifiers()) { +963 if (firstEntry) { +964 firstEntry = false; +965 } else { +966 summary.append(", "); +967 } +968 summary.append(id.getValue()); +969 } +970 summary.append(") : ").append(ids).append(NEW_LINE); +971 } +972 } +973 if (summary.length() > 0) { +974 final String msg = String.format("%n%n" +975 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" +976 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); +977 log(msg, Project.MSG_WARN); +978 } +979 } +980 +981 /** +982 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", +983 * etc.. +984 */ +985 public static class ReportFormats extends EnumeratedAttribute { +986 +987 /** +988 * Returns the list of values for the report format. +989 * +990 * @return the list of values for the report format +991 */ +992 @Override +993 public String[] getValues() { +994 int i = 0; +995 final Format[] formats = Format.values(); +996 final String[] values = new String[formats.length]; +997 for (Format format : formats) { +998 values[i++] = format.name(); +999 } +1000 return values; +1001 } +1002 } +1003 }
      diff --git a/xref/org/owasp/dependencycheck/taskdefs/package-frame.html b/xref/org/owasp/dependencycheck/taskdefs/package-frame.html index 5cb816c61..2d7877d35 100644 --- a/xref/org/owasp/dependencycheck/taskdefs/package-frame.html +++ b/xref/org/owasp/dependencycheck/taskdefs/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/xref/org/owasp/dependencycheck/taskdefs/package-summary.html b/xref/org/owasp/dependencycheck/taskdefs/package-summary.html index a9663c932..7a7886449 100644 --- a/xref/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/xref/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/xref/org/owasp/dependencycheck/utils/Settings.html b/xref/org/owasp/dependencycheck/utils/Settings.html index 7d94000a1..f53fda40e 100644 --- a/xref/org/owasp/dependencycheck/utils/Settings.html +++ b/xref/org/owasp/dependencycheck/utils/Settings.html @@ -198,667 +198,671 @@ 190 */ 191 public static final String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled"; 192 /** -193 * The properties key for whether the Archive analyzer is enabled. +193 * The properties key for whether experimental analyzers are loaded. 194 */ -195 public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled"; +195 public static final String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled"; 196 /** -197 * The properties key for whether the node.js package analyzer is enabled. +197 * The properties key for whether the Archive analyzer is enabled. 198 */ -199 public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled"; +199 public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled"; 200 /** -201 * The properties key for whether the composer lock file analyzer is enabled. +201 * The properties key for whether the node.js package analyzer is enabled. 202 */ -203 public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled"; +203 public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled"; 204 /** -205 * The properties key for whether the Python Distribution analyzer is enabled. +205 * The properties key for whether the composer lock file analyzer is enabled. 206 */ -207 public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled"; +207 public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled"; 208 /** -209 * The properties key for whether the Python Package analyzer is enabled. +209 * The properties key for whether the Python Distribution analyzer is enabled. 210 */ -211 public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled"; +211 public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled"; 212 /** -213 * The properties key for whether the Ruby Gemspec Analyzer is enabled. +213 * The properties key for whether the Python Package analyzer is enabled. 214 */ -215 public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled"; +215 public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled"; 216 /** -217 * The properties key for whether the Autoconf analyzer is enabled. +217 * The properties key for whether the Ruby Gemspec Analyzer is enabled. 218 */ -219 public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled"; +219 public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled"; 220 /** -221 * The properties key for whether the CMake analyzer is enabled. +221 * The properties key for whether the Autoconf analyzer is enabled. 222 */ -223 public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled"; +223 public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled"; 224 /** -225 * The properties key for whether the Ruby Bundler Audit analyzer is enabled. +225 * The properties key for whether the CMake analyzer is enabled. 226 */ -227 public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled"; +227 public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled"; 228 /** -229 * The properties key for whether the .NET Assembly analyzer is enabled. +229 * The properties key for whether the Ruby Bundler Audit analyzer is enabled. 230 */ -231 public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled"; +231 public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled"; 232 /** -233 * The properties key for whether the .NET Nuspec analyzer is enabled. +233 * The properties key for whether the .NET Assembly analyzer is enabled. 234 */ -235 public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled"; +235 public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled"; 236 /** -237 * The properties key for whether the Nexus analyzer is enabled. +237 * The properties key for whether the .NET Nuspec analyzer is enabled. 238 */ -239 public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled"; +239 public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled"; 240 /** -241 * The properties key for the Nexus search URL. +241 * The properties key for whether the Nexus analyzer is enabled. 242 */ -243 public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url"; +243 public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled"; 244 /** -245 * The properties key for using the proxy to reach Nexus. +245 * The properties key for the Nexus search URL. 246 */ -247 public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy"; +247 public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url"; 248 /** -249 * The properties key for whether the Central analyzer is enabled. +249 * The properties key for using the proxy to reach Nexus. 250 */ -251 public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled"; +251 public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy"; 252 /** -253 * The properties key for whether the OpenSSL analyzer is enabled. +253 * The properties key for whether the Central analyzer is enabled. 254 */ -255 public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled"; +255 public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled"; 256 /** -257 * The properties key for the Central search URL. +257 * The properties key for whether the OpenSSL analyzer is enabled. 258 */ -259 public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url"; +259 public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled"; 260 /** -261 * The path to mono, if available. +261 * The properties key for the Central search URL. 262 */ -263 public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path"; +263 public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url"; 264 /** -265 * The path to bundle-audit, if available. +265 * The path to mono, if available. 266 */ -267 public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path"; +267 public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path"; 268 /** -269 * The additional configured zip file extensions, if available. +269 * The path to bundle-audit, if available. 270 */ -271 public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip"; +271 public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path"; 272 /** -273 * The key to obtain the path to the VFEED data file. +273 * The additional configured zip file extensions, if available. 274 */ -275 public static final String VFEED_DATA_FILE = "vfeed.data_file"; +275 public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip"; 276 /** -277 * The key to obtain the VFEED connection string. +277 * The key to obtain the path to the VFEED data file. 278 */ -279 public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string"; -280 -281 /** -282 * The key to obtain the base download URL for the VFeed data file. -283 */ -284 public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url"; +279 public static final String VFEED_DATA_FILE = "vfeed.data_file"; +280 /** +281 * The key to obtain the VFEED connection string. +282 */ +283 public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string"; +284 285 /** -286 * The key to obtain the download file name for the VFeed data. +286 * The key to obtain the base download URL for the VFeed data file. 287 */ -288 public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file"; +288 public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url"; 289 /** -290 * The key to obtain the VFeed update status. +290 * The key to obtain the download file name for the VFeed data. 291 */ -292 public static final String VFEED_UPDATE_STATUS = "vfeed.update_status"; -293 -294 /** -295 * The HTTP request method for query last modified date. -296 */ -297 public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp"; -298 } -299 //</editor-fold> -300 -301 /** -302 * The logger. -303 */ -304 private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class); +292 public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file"; +293 /** +294 * The key to obtain the VFeed update status. +295 */ +296 public static final String VFEED_UPDATE_STATUS = "vfeed.update_status"; +297 +298 /** +299 * The HTTP request method for query last modified date. +300 */ +301 public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp"; +302 } +303 //</editor-fold> +304 305 /** -306 * The properties file location. +306 * The logger. 307 */ -308 private static final String PROPERTIES_FILE = "dependencycheck.properties"; +308 private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class); 309 /** -310 * Thread local settings. +310 * The properties file location. 311 */ -312 private static ThreadLocal<Settings> localSettings = new ThreadLocal<Settings>(); +312 private static final String PROPERTIES_FILE = "dependencycheck.properties"; 313 /** -314 * The properties. +314 * Thread local settings. 315 */ -316 private Properties props = null; -317 -318 /** -319 * Private constructor for the Settings class. This class loads the properties files. -320 * -321 * @param propertiesFilePath the path to the base properties file to load -322 */ -323 private Settings(String propertiesFilePath) { -324 InputStream in = null; -325 props = new Properties(); -326 try { -327 in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath); -328 props.load(in); -329 } catch (IOException ex) { -330 LOGGER.error("Unable to load default settings."); -331 LOGGER.debug("", ex); -332 } finally { -333 if (in != null) { -334 try { -335 in.close(); -336 } catch (IOException ex) { -337 LOGGER.trace("", ex); -338 } -339 } -340 } -341 logProperties("Properties loaded", props); -342 } -343 -344 /** -345 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must -346 * also call Settings.cleanup() to properly release resources. -347 */ -348 public static void initialize() { -349 localSettings.set(new Settings(PROPERTIES_FILE)); -350 } -351 -352 /** -353 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must -354 * also call Settings.cleanup() to properly release resources. -355 * -356 * @param propertiesFilePath the path to the base properties file to load -357 */ -358 public static void initialize(String propertiesFilePath) { -359 localSettings.set(new Settings(propertiesFilePath)); -360 } -361 -362 /** -363 * Cleans up resources to prevent memory leaks. -364 * -365 */ -366 public static void cleanup() { -367 cleanup(true); -368 } -369 -370 /** -371 * Cleans up resources to prevent memory leaks. -372 * -373 * @param deleteTemporary flag indicating whether any temporary directories generated should be removed -374 */ -375 public static void cleanup(boolean deleteTemporary) { -376 if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) { -377 FileUtils.delete(tempDirectory); -378 if (tempDirectory.exists()) { -379 try { -380 Thread.sleep(2000); -381 } catch (InterruptedException ex) { -382 LOGGER.trace("ignore", ex); -383 } -384 FileUtils.delete(tempDirectory); -385 } -386 } -387 try { -388 localSettings.remove(); -389 } catch (Throwable ex) { -390 LOGGER.debug("Error cleaning up Settings", ex); -391 } -392 } -393 -394 /** -395 * Gets the underlying instance of the Settings object. -396 * -397 * @return the Settings object -398 */ -399 public static Settings getInstance() { -400 return localSettings.get(); -401 } -402 -403 /** -404 * Sets the instance of the Settings object to use in this thread. -405 * -406 * @param instance the instance of the settings object to use in this thread -407 */ -408 public static void setInstance(Settings instance) { -409 localSettings.set(instance); -410 } -411 -412 /** -413 * Logs the properties. This will not log any properties that contain 'password' in the key. -414 * -415 * @param header the header to print with the log message -416 * @param properties the properties to log -417 */ -418 private static void logProperties(String header, Properties properties) { -419 if (LOGGER.isDebugEnabled()) { -420 final StringWriter sw = new StringWriter(); -421 PrintWriter pw = null; -422 try { -423 pw = new PrintWriter(sw); -424 pw.format("%s:%n%n", header); -425 final Enumeration<?> e = properties.propertyNames(); -426 while (e.hasMoreElements()) { -427 final String key = (String) e.nextElement(); -428 if (key.contains("password")) { -429 pw.format("%s='*****'%n", key); -430 } else { -431 final String value = properties.getProperty(key); -432 if (value != null) { -433 pw.format("%s='%s'%n", key, value); -434 } -435 } -436 } -437 pw.flush(); -438 LOGGER.debug(sw.toString()); -439 } finally { -440 if (pw != null) { -441 pw.close(); -442 } -443 } -444 -445 } -446 } -447 -448 /** -449 * Sets a property value. -450 * -451 * @param key the key for the property -452 * @param value the value for the property -453 */ -454 public static void setString(String key, String value) { -455 localSettings.get().props.setProperty(key, value); -456 LOGGER.debug("Setting: {}='{}'", key, value); -457 } -458 -459 /** -460 * Sets a property value only if the value is not null. -461 * -462 * @param key the key for the property -463 * @param value the value for the property -464 */ -465 public static void setStringIfNotNull(String key, String value) { -466 if (null != value) { -467 setString(key, value); -468 } -469 } -470 -471 /** -472 * Sets a property value only if the value is not null and not empty. -473 * -474 * @param key the key for the property -475 * @param value the value for the property -476 */ -477 public static void setStringIfNotEmpty(String key, String value) { -478 if (null != value && !value.isEmpty()) { -479 setString(key, value); -480 } -481 } -482 -483 /** -484 * Sets a property value. -485 * -486 * @param key the key for the property -487 * @param value the value for the property -488 */ -489 public static void setBoolean(String key, boolean value) { -490 setString(key, Boolean.toString(value)); -491 } -492 -493 /** -494 * Sets a property value only if the value is not null. -495 * -496 * @param key the key for the property -497 * @param value the value for the property -498 */ -499 public static void setBooleanIfNotNull(String key, Boolean value) { -500 if (null != value) { -501 setBoolean(key, value); -502 } -503 } -504 -505 /** -506 * Sets a property value. -507 * -508 * @param key the key for the property -509 * @param value the value for the property -510 */ -511 public static void setInt(String key, int value) { -512 localSettings.get().props.setProperty(key, String.valueOf(value)); -513 LOGGER.debug("Setting: {}='{}'", key, value); -514 } -515 -516 /** -517 * Sets a property value only if the value is not null. -518 * -519 * @param key the key for the property -520 * @param value the value for the property -521 */ -522 public static void setIntIfNotNull(String key, Integer value) { -523 if (null != value) { -524 setInt(key, value); -525 } -526 } -527 -528 /** -529 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -530 * file.<br><br> -531 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. -532 * -533 * @param filePath the path to the properties file to merge. -534 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file -535 * @throws IOException is thrown when there is an exception loading/merging the properties -536 */ -537 public static void mergeProperties(File filePath) throws FileNotFoundException, IOException { -538 FileInputStream fis = null; -539 try { -540 fis = new FileInputStream(filePath); -541 mergeProperties(fis); -542 } finally { -543 if (fis != null) { -544 try { -545 fis.close(); -546 } catch (IOException ex) { -547 LOGGER.trace("close error", ex); -548 } -549 } -550 } -551 } -552 -553 /** -554 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -555 * file.<br><br> -556 * Note: even if using this method - system properties will be loaded before properties loaded from files. -557 * -558 * @param filePath the path to the properties file to merge. -559 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file -560 * @throws IOException is thrown when there is an exception loading/merging the properties -561 */ -562 public static void mergeProperties(String filePath) throws FileNotFoundException, IOException { -563 FileInputStream fis = null; -564 try { -565 fis = new FileInputStream(filePath); -566 mergeProperties(fis); -567 } finally { -568 if (fis != null) { -569 try { -570 fis.close(); -571 } catch (IOException ex) { -572 LOGGER.trace("close error", ex); -573 } -574 } -575 } -576 } -577 -578 /** -579 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -580 * file.<br><br> -581 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. -582 * -583 * @param stream an Input Stream pointing at a properties file to merge -584 * @throws IOException is thrown when there is an exception loading/merging the properties -585 */ -586 public static void mergeProperties(InputStream stream) throws IOException { -587 localSettings.get().props.load(stream); -588 logProperties("Properties updated via merge", localSettings.get().props); -589 } -590 -591 /** -592 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via -593 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained -594 * configuration file. -595 * -596 * @param key the key to lookup within the properties file -597 * @return the property from the properties file converted to a File object -598 */ -599 public static File getFile(String key) { -600 final String file = getString(key); -601 if (file == null) { -602 return null; -603 } -604 return new File(file); -605 } -606 -607 /** -608 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via -609 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained -610 * configuration file. -611 * -612 * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the -613 * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this -614 * class. +316 private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>(); +317 /** +318 * The properties. +319 */ +320 private Properties props = null; +321 +322 /** +323 * Private constructor for the Settings class. This class loads the properties files. +324 * +325 * @param propertiesFilePath the path to the base properties file to load +326 */ +327 private Settings(String propertiesFilePath) { +328 InputStream in = null; +329 props = new Properties(); +330 try { +331 in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath); +332 props.load(in); +333 } catch (IOException ex) { +334 LOGGER.error("Unable to load default settings."); +335 LOGGER.debug("", ex); +336 } finally { +337 if (in != null) { +338 try { +339 in.close(); +340 } catch (IOException ex) { +341 LOGGER.trace("", ex); +342 } +343 } +344 } +345 logProperties("Properties loaded", props); +346 } +347 +348 /** +349 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must +350 * also call Settings.cleanup() to properly release resources. +351 */ +352 public static void initialize() { +353 LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE)); +354 } +355 +356 /** +357 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must +358 * also call Settings.cleanup() to properly release resources. +359 * +360 * @param propertiesFilePath the path to the base properties file to load +361 */ +362 public static void initialize(String propertiesFilePath) { +363 LOCAL_SETTINGS.set(new Settings(propertiesFilePath)); +364 } +365 +366 /** +367 * Cleans up resources to prevent memory leaks. +368 * +369 */ +370 public static void cleanup() { +371 cleanup(true); +372 } +373 +374 /** +375 * Cleans up resources to prevent memory leaks. +376 * +377 * @param deleteTemporary flag indicating whether any temporary directories generated should be removed +378 */ +379 public static void cleanup(boolean deleteTemporary) { +380 if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) { +381 FileUtils.delete(tempDirectory); +382 if (tempDirectory.exists()) { +383 try { +384 Thread.sleep(2000); +385 } catch (InterruptedException ex) { +386 LOGGER.trace("ignore", ex); +387 } +388 FileUtils.delete(tempDirectory); +389 } +390 } +391 try { +392 LOCAL_SETTINGS.remove(); +393 } catch (Throwable ex) { +394 LOGGER.debug("Error cleaning up Settings", ex); +395 } +396 } +397 +398 /** +399 * Gets the underlying instance of the Settings object. +400 * +401 * @return the Settings object +402 */ +403 public static Settings getInstance() { +404 return LOCAL_SETTINGS.get(); +405 } +406 +407 /** +408 * Sets the instance of the Settings object to use in this thread. +409 * +410 * @param instance the instance of the settings object to use in this thread +411 */ +412 public static void setInstance(Settings instance) { +413 LOCAL_SETTINGS.set(instance); +414 } +415 +416 /** +417 * Logs the properties. This will not log any properties that contain 'password' in the key. +418 * +419 * @param header the header to print with the log message +420 * @param properties the properties to log +421 */ +422 private static void logProperties(String header, Properties properties) { +423 if (LOGGER.isDebugEnabled()) { +424 final StringWriter sw = new StringWriter(); +425 PrintWriter pw = null; +426 try { +427 pw = new PrintWriter(sw); +428 pw.format("%s:%n%n", header); +429 final Enumeration<?> e = properties.propertyNames(); +430 while (e.hasMoreElements()) { +431 final String key = (String) e.nextElement(); +432 if (key.contains("password")) { +433 pw.format("%s='*****'%n", key); +434 } else { +435 final String value = properties.getProperty(key); +436 if (value != null) { +437 pw.format("%s='%s'%n", key, value); +438 } +439 } +440 } +441 pw.flush(); +442 LOGGER.debug(sw.toString()); +443 } finally { +444 if (pw != null) { +445 pw.close(); +446 } +447 } +448 +449 } +450 } +451 +452 /** +453 * Sets a property value. +454 * +455 * @param key the key for the property +456 * @param value the value for the property +457 */ +458 public static void setString(String key, String value) { +459 LOCAL_SETTINGS.get().props.setProperty(key, value); +460 LOGGER.debug("Setting: {}='{}'", key, value); +461 } +462 +463 /** +464 * Sets a property value only if the value is not null. +465 * +466 * @param key the key for the property +467 * @param value the value for the property +468 */ +469 public static void setStringIfNotNull(String key, String value) { +470 if (null != value) { +471 setString(key, value); +472 } +473 } +474 +475 /** +476 * Sets a property value only if the value is not null and not empty. +477 * +478 * @param key the key for the property +479 * @param value the value for the property +480 */ +481 public static void setStringIfNotEmpty(String key, String value) { +482 if (null != value && !value.isEmpty()) { +483 setString(key, value); +484 } +485 } +486 +487 /** +488 * Sets a property value. +489 * +490 * @param key the key for the property +491 * @param value the value for the property +492 */ +493 public static void setBoolean(String key, boolean value) { +494 setString(key, Boolean.toString(value)); +495 } +496 +497 /** +498 * Sets a property value only if the value is not null. +499 * +500 * @param key the key for the property +501 * @param value the value for the property +502 */ +503 public static void setBooleanIfNotNull(String key, Boolean value) { +504 if (null != value) { +505 setBoolean(key, value); +506 } +507 } +508 +509 /** +510 * Sets a property value. +511 * +512 * @param key the key for the property +513 * @param value the value for the property +514 */ +515 public static void setInt(String key, int value) { +516 LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value)); +517 LOGGER.debug("Setting: {}='{}'", key, value); +518 } +519 +520 /** +521 * Sets a property value only if the value is not null. +522 * +523 * @param key the key for the property +524 * @param value the value for the property +525 */ +526 public static void setIntIfNotNull(String key, Integer value) { +527 if (null != value) { +528 setInt(key, value); +529 } +530 } +531 +532 /** +533 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties +534 * file.<br><br> +535 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. +536 * +537 * @param filePath the path to the properties file to merge. +538 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file +539 * @throws IOException is thrown when there is an exception loading/merging the properties +540 */ +541 public static void mergeProperties(File filePath) throws FileNotFoundException, IOException { +542 FileInputStream fis = null; +543 try { +544 fis = new FileInputStream(filePath); +545 mergeProperties(fis); +546 } finally { +547 if (fis != null) { +548 try { +549 fis.close(); +550 } catch (IOException ex) { +551 LOGGER.trace("close error", ex); +552 } +553 } +554 } +555 } +556 +557 /** +558 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties +559 * file.<br><br> +560 * Note: even if using this method - system properties will be loaded before properties loaded from files. +561 * +562 * @param filePath the path to the properties file to merge. +563 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file +564 * @throws IOException is thrown when there is an exception loading/merging the properties +565 */ +566 public static void mergeProperties(String filePath) throws FileNotFoundException, IOException { +567 FileInputStream fis = null; +568 try { +569 fis = new FileInputStream(filePath); +570 mergeProperties(fis); +571 } finally { +572 if (fis != null) { +573 try { +574 fis.close(); +575 } catch (IOException ex) { +576 LOGGER.trace("close error", ex); +577 } +578 } +579 } +580 } +581 +582 /** +583 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties +584 * file.<br><br> +585 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. +586 * +587 * @param stream an Input Stream pointing at a properties file to merge +588 * @throws IOException is thrown when there is an exception loading/merging the properties +589 */ +590 public static void mergeProperties(InputStream stream) throws IOException { +591 LOCAL_SETTINGS.get().props.load(stream); +592 logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props); +593 } +594 +595 /** +596 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via +597 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained +598 * configuration file. +599 * +600 * @param key the key to lookup within the properties file +601 * @return the property from the properties file converted to a File object +602 */ +603 public static File getFile(String key) { +604 final String file = getString(key); +605 if (file == null) { +606 return null; +607 } +608 return new File(file); +609 } +610 +611 /** +612 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via +613 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained +614 * configuration file. 615 * -616 * @param key the key to lookup within the properties file -617 * @return the property from the properties file converted to a File object -618 */ -619 protected static File getDataFile(String key) { -620 final String file = getString(key); -621 LOGGER.debug("Settings.getDataFile() - file: '{}'", file); -622 if (file == null) { -623 return null; -624 } -625 if (file.startsWith("[JAR]")) { -626 LOGGER.debug("Settings.getDataFile() - transforming filename"); -627 final File jarPath = getJarPath(); -628 LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString()); -629 final File retVal = new File(jarPath, file.substring(6)); -630 LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString()); -631 return retVal; -632 } -633 return new File(file); -634 } -635 -636 /** -637 * Attempts to retrieve the folder containing the Jar file containing the Settings class. -638 * -639 * @return a File object -640 */ -641 private static File getJarPath() { -642 final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath(); -643 String decodedPath = "."; -644 try { -645 decodedPath = URLDecoder.decode(jarPath, "UTF-8"); -646 } catch (UnsupportedEncodingException ex) { -647 LOGGER.trace("", ex); -648 } -649 -650 final File path = new File(decodedPath); -651 if (path.getName().toLowerCase().endsWith(".jar")) { -652 return path.getParentFile(); -653 } else { -654 return new File("."); -655 } -656 } -657 -658 /** -659 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value -660 * argument - this method will return the value from the system properties before the values in the contained configuration -661 * file. -662 * -663 * @param key the key to lookup within the properties file -664 * @param defaultValue the default value for the requested property -665 * @return the property from the properties file -666 */ -667 public static String getString(String key, String defaultValue) { -668 final String str = System.getProperty(key, localSettings.get().props.getProperty(key, defaultValue)); -669 return str; -670 } -671 -672 /** -673 * A reference to the temporary directory; used incase it needs to be deleted during cleanup. -674 */ -675 private static File tempDirectory = null; -676 -677 /** -678 * Returns the temporary directory. -679 * -680 * @return the temporary directory -681 * @throws java.io.IOException thrown if the temporary directory does not exist and cannot be created -682 */ -683 public static File getTempDirectory() throws IOException { -684 final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp"); -685 if (!tmpDir.exists() && !tmpDir.mkdirs()) { -686 final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath()); -687 throw new IOException(msg); -688 } -689 tempDirectory = tmpDir; -690 return tmpDir; -691 } -692 -693 /** -694 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value -695 * argument - this method will return the value from the system properties before the values in the contained configuration -696 * file. -697 * -698 * @param key the key to lookup within the properties file -699 * @return the property from the properties file -700 */ -701 public static String getString(String key) { -702 return System.getProperty(key, localSettings.get().props.getProperty(key)); -703 } -704 -705 /** -706 * Removes a property from the local properties collection. This is mainly used in test cases. -707 * -708 * @param key the property key to remove -709 */ -710 public static void removeProperty(String key) { -711 localSettings.get().props.remove(key); -712 } -713 -714 /** -715 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the -716 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -717 * configuration file. -718 * -719 * @param key the key to lookup within the properties file -720 * @return the property from the properties file -721 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -722 */ -723 public static int getInt(String key) throws InvalidSettingException { -724 try { -725 return Integer.parseInt(Settings.getString(key)); -726 } catch (NumberFormatException ex) { -727 throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex); -728 } -729 } -730 -731 /** -732 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the -733 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -734 * configuration file. -735 * -736 * @param key the key to lookup within the properties file -737 * @param defaultValue the default value to return -738 * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to -739 * an integer -740 */ -741 public static int getInt(String key, int defaultValue) { -742 int value; -743 try { -744 value = Integer.parseInt(Settings.getString(key)); -745 } catch (NumberFormatException ex) { -746 if (!Settings.getString(key, "").isEmpty()) { -747 LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue); -748 } -749 value = defaultValue; -750 } -751 return value; -752 } -753 -754 /** -755 * Returns a long value from the properties file. If the value was specified as a system property or passed in via the -756 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -757 * configuration file. -758 * -759 * @param key the key to lookup within the properties file -760 * @return the property from the properties file -761 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -762 */ -763 public static long getLong(String key) throws InvalidSettingException { -764 try { -765 return Long.parseLong(Settings.getString(key)); -766 } catch (NumberFormatException ex) { -767 throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex); -768 } -769 } -770 -771 /** -772 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the -773 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the -774 * contained configuration file. -775 * -776 * @param key the key to lookup within the properties file -777 * @return the property from the properties file -778 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -779 */ -780 public static boolean getBoolean(String key) throws InvalidSettingException { -781 return Boolean.parseBoolean(Settings.getString(key)); -782 } -783 -784 /** -785 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the -786 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the -787 * contained configuration file. -788 * -789 * @param key the key to lookup within the properties file -790 * @param defaultValue the default value to return if the setting does not exist -791 * @return the property from the properties file -792 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -793 */ -794 public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException { -795 return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue))); -796 } -797 -798 /** -799 * Returns a connection string from the configured properties. If the connection string contains a %s, this method will -800 * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not -801 * exists it will be created. -802 * -803 * @param connectionStringKey the property file key for the connection string -804 * @param dbFileNameKey the settings key for the db filename -805 * @return the connection string -806 * @throws IOException thrown the data directory cannot be created -807 * @throws InvalidSettingException thrown if there is an invalid setting -808 */ -809 public static String getConnectionString(String connectionStringKey, String dbFileNameKey) -810 throws IOException, InvalidSettingException { -811 final String connStr = Settings.getString(connectionStringKey); -812 if (connStr == null) { -813 final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey); -814 throw new InvalidSettingException(msg); -815 } -816 if (connStr.contains("%s")) { -817 final File directory = getDataDirectory(); -818 String fileName = null; -819 if (dbFileNameKey != null) { -820 fileName = Settings.getString(dbFileNameKey); -821 } -822 if (fileName == null) { -823 final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.", -824 dbFileNameKey); -825 throw new InvalidSettingException(msg); -826 } -827 if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) { -828 fileName = fileName.substring(0, fileName.length() - 6); -829 } -830 // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed -831 final File dbFile = new File(directory, fileName); -832 final String cString = String.format(connStr, dbFile.getCanonicalPath()); -833 LOGGER.debug("Connection String: '{}'", cString); -834 return cString; -835 } -836 return connStr; -837 } -838 -839 /** -840 * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the -841 * embedded H2 database. This is public solely for some unit tests; otherwise this should be private. -842 * -843 * @return the data directory to store data files -844 * @throws IOException is thrown if an IOException occurs of course... -845 */ -846 public static File getDataDirectory() throws IOException { -847 final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY); -848 if (path.exists() || path.mkdirs()) { -849 return path; -850 } -851 throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath())); -852 } -853 } +616 * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the +617 * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this +618 * class. +619 * +620 * @param key the key to lookup within the properties file +621 * @return the property from the properties file converted to a File object +622 */ +623 protected static File getDataFile(String key) { +624 final String file = getString(key); +625 LOGGER.debug("Settings.getDataFile() - file: '{}'", file); +626 if (file == null) { +627 return null; +628 } +629 if (file.startsWith("[JAR]")) { +630 LOGGER.debug("Settings.getDataFile() - transforming filename"); +631 final File jarPath = getJarPath(); +632 LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString()); +633 final File retVal = new File(jarPath, file.substring(6)); +634 LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString()); +635 return retVal; +636 } +637 return new File(file); +638 } +639 +640 /** +641 * Attempts to retrieve the folder containing the Jar file containing the Settings class. +642 * +643 * @return a File object +644 */ +645 private static File getJarPath() { +646 final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath(); +647 String decodedPath = "."; +648 try { +649 decodedPath = URLDecoder.decode(jarPath, "UTF-8"); +650 } catch (UnsupportedEncodingException ex) { +651 LOGGER.trace("", ex); +652 } +653 +654 final File path = new File(decodedPath); +655 if (path.getName().toLowerCase().endsWith(".jar")) { +656 return path.getParentFile(); +657 } else { +658 return new File("."); +659 } +660 } +661 +662 /** +663 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value +664 * argument - this method will return the value from the system properties before the values in the contained configuration +665 * file. +666 * +667 * @param key the key to lookup within the properties file +668 * @param defaultValue the default value for the requested property +669 * @return the property from the properties file +670 */ +671 public static String getString(String key, String defaultValue) { +672 final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue)); +673 return str; +674 } +675 +676 /** +677 * A reference to the temporary directory; used incase it needs to be deleted during cleanup. +678 */ +679 private static File tempDirectory = null; +680 +681 /** +682 * Returns the temporary directory. +683 * +684 * @return the temporary directory +685 * @throws java.io.IOException thrown if the temporary directory does not exist and cannot be created +686 */ +687 public static File getTempDirectory() throws IOException { +688 final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp"); +689 if (!tmpDir.exists() && !tmpDir.mkdirs()) { +690 final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath()); +691 throw new IOException(msg); +692 } +693 tempDirectory = tmpDir; +694 return tmpDir; +695 } +696 +697 /** +698 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value +699 * argument - this method will return the value from the system properties before the values in the contained configuration +700 * file. +701 * +702 * @param key the key to lookup within the properties file +703 * @return the property from the properties file +704 */ +705 public static String getString(String key) { +706 return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key)); +707 } +708 +709 /** +710 * Removes a property from the local properties collection. This is mainly used in test cases. +711 * +712 * @param key the property key to remove +713 */ +714 public static void removeProperty(String key) { +715 LOCAL_SETTINGS.get().props.remove(key); +716 } +717 +718 /** +719 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the +720 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained +721 * configuration file. +722 * +723 * @param key the key to lookup within the properties file +724 * @return the property from the properties file +725 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +726 */ +727 public static int getInt(String key) throws InvalidSettingException { +728 try { +729 return Integer.parseInt(Settings.getString(key)); +730 } catch (NumberFormatException ex) { +731 throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex); +732 } +733 } +734 +735 /** +736 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the +737 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained +738 * configuration file. +739 * +740 * @param key the key to lookup within the properties file +741 * @param defaultValue the default value to return +742 * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to +743 * an integer +744 */ +745 public static int getInt(String key, int defaultValue) { +746 int value; +747 try { +748 value = Integer.parseInt(Settings.getString(key)); +749 } catch (NumberFormatException ex) { +750 if (!Settings.getString(key, "").isEmpty()) { +751 LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue); +752 } +753 value = defaultValue; +754 } +755 return value; +756 } +757 +758 /** +759 * Returns a long value from the properties file. If the value was specified as a system property or passed in via the +760 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained +761 * configuration file. +762 * +763 * @param key the key to lookup within the properties file +764 * @return the property from the properties file +765 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +766 */ +767 public static long getLong(String key) throws InvalidSettingException { +768 try { +769 return Long.parseLong(Settings.getString(key)); +770 } catch (NumberFormatException ex) { +771 throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex); +772 } +773 } +774 +775 /** +776 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the +777 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the +778 * contained configuration file. +779 * +780 * @param key the key to lookup within the properties file +781 * @return the property from the properties file +782 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +783 */ +784 public static boolean getBoolean(String key) throws InvalidSettingException { +785 return Boolean.parseBoolean(Settings.getString(key)); +786 } +787 +788 /** +789 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the +790 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the +791 * contained configuration file. +792 * +793 * @param key the key to lookup within the properties file +794 * @param defaultValue the default value to return if the setting does not exist +795 * @return the property from the properties file +796 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +797 */ +798 public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException { +799 return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue))); +800 } +801 +802 /** +803 * Returns a connection string from the configured properties. If the connection string contains a %s, this method will +804 * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not +805 * exists it will be created. +806 * +807 * @param connectionStringKey the property file key for the connection string +808 * @param dbFileNameKey the settings key for the db filename +809 * @return the connection string +810 * @throws IOException thrown the data directory cannot be created +811 * @throws InvalidSettingException thrown if there is an invalid setting +812 */ +813 public static String getConnectionString(String connectionStringKey, String dbFileNameKey) +814 throws IOException, InvalidSettingException { +815 final String connStr = Settings.getString(connectionStringKey); +816 if (connStr == null) { +817 final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey); +818 throw new InvalidSettingException(msg); +819 } +820 if (connStr.contains("%s")) { +821 final File directory = getDataDirectory(); +822 String fileName = null; +823 if (dbFileNameKey != null) { +824 fileName = Settings.getString(dbFileNameKey); +825 } +826 if (fileName == null) { +827 final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.", +828 dbFileNameKey); +829 throw new InvalidSettingException(msg); +830 } +831 if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) { +832 fileName = fileName.substring(0, fileName.length() - 6); +833 } +834 // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed +835 final File dbFile = new File(directory, fileName); +836 final String cString = String.format(connStr, dbFile.getCanonicalPath()); +837 LOGGER.debug("Connection String: '{}'", cString); +838 return cString; +839 } +840 return connStr; +841 } +842 +843 /** +844 * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the +845 * embedded H2 database. This is public solely for some unit tests; otherwise this should be private. +846 * +847 * @return the data directory to store data files +848 * @throws IOException is thrown if an IOException occurs of course... +849 */ +850 public static File getDataDirectory() throws IOException { +851 final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY); +852 if (path.exists() || path.mkdirs()) { +853 return path; +854 } +855 throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath())); +856 } +857 }
      diff --git a/xref/org/owasp/dependencycheck/utils/package-frame.html b/xref/org/owasp/dependencycheck/utils/package-frame.html index c3264f5c8..821f495dd 100644 --- a/xref/org/owasp/dependencycheck/utils/package-frame.html +++ b/xref/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/xref/org/owasp/dependencycheck/utils/package-summary.html b/xref/org/owasp/dependencycheck/utils/package-summary.html index aac4e26f0..62b71e100 100644 --- a/xref/org/owasp/dependencycheck/utils/package-summary.html +++ b/xref/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.utils + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.utils diff --git a/xref/org/owasp/dependencycheck/xml/pom/Model.html b/xref/org/owasp/dependencycheck/xml/pom/Model.html index 902aa750d..ae086b16f 100644 --- a/xref/org/owasp/dependencycheck/xml/pom/Model.html +++ b/xref/org/owasp/dependencycheck/xml/pom/Model.html @@ -270,92 +270,120 @@ 262 } 263 264 /** -265 * Process the Maven properties file and interpolate all properties. -266 * -267 * @param properties new value of properties -268 */ -269 public void processProperties(Properties properties) { -270 this.groupId = interpolateString(this.groupId, properties); -271 this.artifactId = interpolateString(this.artifactId, properties); -272 this.version = interpolateString(this.version, properties); -273 this.description = interpolateString(this.description, properties); -274 for (License l : this.getLicenses()) { -275 l.setName(interpolateString(l.getName(), properties)); -276 l.setUrl(interpolateString(l.getUrl(), properties)); -277 } -278 this.name = interpolateString(this.name, properties); -279 this.organization = interpolateString(this.organization, properties); -280 this.parentGroupId = interpolateString(this.parentGroupId, properties); -281 this.parentArtifactId = interpolateString(this.parentArtifactId, properties); -282 this.parentVersion = interpolateString(this.parentVersion, properties); -283 -284 } -285 -286 /** -287 * <p> -288 * A utility function that will interpolate strings based on values given in the properties file. It will also interpolate the -289 * strings contained within the properties file so that properties can reference other properties.</p> -290 * <p> -291 * <b>Note:</b> if there is no property found the reference will be removed. In other words, if the interpolated string will -292 * be replaced with an empty string. -293 * </p> -294 * <p> -295 * Example:</p> -296 * <code> -297 * Properties p = new Properties(); -298 * p.setProperty("key", "value"); -299 * String s = interpolateString("'${key}' and '${nothing}'", p); -300 * System.out.println(s); -301 * </code> -302 * <p> -303 * Will result in:</p> -304 * <code> -305 * 'value' and '' -306 * </code> -307 * -308 * @param text the string that contains references to properties. -309 * @param properties a collection of properties that may be referenced within the text. -310 * @return the interpolated text. -311 */ -312 public static String interpolateString(String text, Properties properties) { -313 if (null == text || null == properties) { -314 return text; -315 } -316 final StrSubstitutor substitutor = new StrSubstitutor(new PropertyLookup(properties)); -317 return substitutor.replace(text); -318 } -319 -320 /** -321 * Utility class that can provide values from a Properties object to a StrSubstitutor. -322 */ -323 private static class PropertyLookup extends StrLookup { -324 -325 /** -326 * Reference to the properties to lookup. -327 */ -328 private final Properties props; -329 -330 /** -331 * Constructs a new property lookup. -332 * -333 * @param props the properties to wrap. -334 */ -335 PropertyLookup(Properties props) { -336 this.props = props; -337 } -338 -339 /** -340 * Looks up the given property. -341 * -342 * @param key the key to the property -343 * @return the value of the property specified by the key -344 */ -345 @Override -346 public String lookup(String key) { -347 return props.getProperty(key); -348 } -349 } -350 } +265 * The project URL. +266 */ +267 private String projectURL; +268 +269 /** +270 * Get the value of projectURL. +271 * +272 * @return the value of projectURL +273 */ +274 public String getProjectURL() { +275 return projectURL; +276 } +277 +278 /** +279 * Set the value of projectURL. +280 * +281 * @param projectURL new value of projectURL +282 */ +283 public void setProjectURL(String projectURL) { +284 this.projectURL = projectURL; +285 } +286 +287 /** +288 * Process the Maven properties file and interpolate all properties. +289 * +290 * @param properties new value of properties +291 */ +292 public void processProperties(Properties properties) { +293 this.groupId = interpolateString(this.groupId, properties); +294 this.artifactId = interpolateString(this.artifactId, properties); +295 this.version = interpolateString(this.version, properties); +296 this.description = interpolateString(this.description, properties); +297 for (License l : this.getLicenses()) { +298 l.setName(interpolateString(l.getName(), properties)); +299 l.setUrl(interpolateString(l.getUrl(), properties)); +300 } +301 this.name = interpolateString(this.name, properties); +302 this.projectURL = interpolateString(this.projectURL, properties); +303 this.organization = interpolateString(this.organization, properties); +304 this.parentGroupId = interpolateString(this.parentGroupId, properties); +305 this.parentArtifactId = interpolateString(this.parentArtifactId, properties); +306 this.parentVersion = interpolateString(this.parentVersion, properties); +307 } +308 +309 /** +310 * <p> +311 * A utility function that will interpolate strings based on values given in +312 * the properties file. It will also interpolate the strings contained +313 * within the properties file so that properties can reference other +314 * properties.</p> +315 * <p> +316 * <b>Note:</b> if there is no property found the reference will be removed. +317 * In other words, if the interpolated string will be replaced with an empty +318 * string. +319 * </p> +320 * <p> +321 * Example:</p> +322 * <code> +323 * Properties p = new Properties(); +324 * p.setProperty("key", "value"); +325 * String s = interpolateString("'${key}' and '${nothing}'", p); +326 * System.out.println(s); +327 * </code> +328 * <p> +329 * Will result in:</p> +330 * <code> +331 * 'value' and '' +332 * </code> +333 * +334 * @param text the string that contains references to properties. +335 * @param properties a collection of properties that may be referenced +336 * within the text. +337 * @return the interpolated text. +338 */ +339 public static String interpolateString(String text, Properties properties) { +340 if (null == text || null == properties) { +341 return text; +342 } +343 final StrSubstitutor substitutor = new StrSubstitutor(new PropertyLookup(properties)); +344 return substitutor.replace(text); +345 } +346 +347 /** +348 * Utility class that can provide values from a Properties object to a +349 * StrSubstitutor. +350 */ +351 private static class PropertyLookup extends StrLookup { +352 +353 /** +354 * Reference to the properties to lookup. +355 */ +356 private final Properties props; +357 +358 /** +359 * Constructs a new property lookup. +360 * +361 * @param props the properties to wrap. +362 */ +363 PropertyLookup(Properties props) { +364 this.props = props; +365 } +366 +367 /** +368 * Looks up the given property. +369 * +370 * @param key the key to the property +371 * @return the value of the property specified by the key +372 */ +373 @Override +374 public String lookup(String key) { +375 return props.getProperty(key); +376 } +377 } +378 }
      diff --git a/xref/org/owasp/dependencycheck/xml/pom/PomHandler.html b/xref/org/owasp/dependencycheck/xml/pom/PomHandler.html index cc7ac93dc..826c65500 100644 --- a/xref/org/owasp/dependencycheck/xml/pom/PomHandler.html +++ b/xref/org/owasp/dependencycheck/xml/pom/PomHandler.html @@ -153,49 +153,51 @@ 145 model.setOrganization(currentText.toString()); 146 } else if (DESCRIPTION.equals(qName)) { 147 model.setDescription(currentText.toString()); -148 } -149 } else if (PARENT.equals(parentNode)) { -150 if (GROUPID.equals(qName)) { -151 model.setParentGroupId(currentText.toString()); -152 } else if (ARTIFACTID.equals(qName)) { -153 model.setParentArtifactId(currentText.toString()); -154 } else if (VERSION.equals(qName)) { -155 model.setParentVersion(currentText.toString()); -156 } -157 } else if (LICENSE.equals(parentNode)) { -158 if (license != null) { -159 if (NAME.equals(qName)) { -160 license.setName(currentText.toString()); -161 } else if (URL.equals(qName)) { -162 license.setUrl(currentText.toString()); -163 } -164 //} else { -165 //TODO add error logging -166 } -167 } else if (LICENSES.equals(parentNode)) { -168 if (LICENSE.equals(qName)) { -169 if (license != null) { -170 model.addLicense(license); -171 //} else { -172 //TODO add error logging -173 } -174 } -175 } -176 } -177 -178 /** -179 * Collects the body text of the node being processed. -180 * -181 * @param ch the char array of text -182 * @param start the start position to copy text from in the char array -183 * @param length the number of characters to copy from the char array -184 * @throws SAXException thrown if there is a parsing exception -185 */ -186 @Override -187 public void characters(char[] ch, int start, int length) throws SAXException { -188 currentText.append(ch, start, length); -189 } -190 } +148 } else if (URL.equals(qName)) { +149 model.setProjectURL(currentText.toString()); +150 } +151 } else if (PARENT.equals(parentNode)) { +152 if (GROUPID.equals(qName)) { +153 model.setParentGroupId(currentText.toString()); +154 } else if (ARTIFACTID.equals(qName)) { +155 model.setParentArtifactId(currentText.toString()); +156 } else if (VERSION.equals(qName)) { +157 model.setParentVersion(currentText.toString()); +158 } +159 } else if (LICENSE.equals(parentNode)) { +160 if (license != null) { +161 if (NAME.equals(qName)) { +162 license.setName(currentText.toString()); +163 } else if (URL.equals(qName)) { +164 license.setUrl(currentText.toString()); +165 } +166 //} else { +167 //TODO add error logging +168 } +169 } else if (LICENSES.equals(parentNode)) { +170 if (LICENSE.equals(qName)) { +171 if (license != null) { +172 model.addLicense(license); +173 //} else { +174 //TODO add error logging +175 } +176 } +177 } +178 } +179 +180 /** +181 * Collects the body text of the node being processed. +182 * +183 * @param ch the char array of text +184 * @param start the start position to copy text from in the char array +185 * @param length the number of characters to copy from the char array +186 * @throws SAXException thrown if there is a parsing exception +187 */ +188 @Override +189 public void characters(char[] ch, int start, int length) throws SAXException { +190 currentText.append(ch, start, length); +191 } +192 }
      diff --git a/xref/org/owasp/dependencycheck/xml/pom/package-frame.html b/xref/org/owasp/dependencycheck/xml/pom/package-frame.html index 3b567ed70..3694b2a26 100644 --- a/xref/org/owasp/dependencycheck/xml/pom/package-frame.html +++ b/xref/org/owasp/dependencycheck/xml/pom/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/xref/org/owasp/dependencycheck/xml/pom/package-summary.html b/xref/org/owasp/dependencycheck/xml/pom/package-summary.html index 254c8f47a..c10b5b094 100644 --- a/xref/org/owasp/dependencycheck/xml/pom/package-summary.html +++ b/xref/org/owasp/dependencycheck/xml/pom/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/xref/org/slf4j/impl/StaticLoggerBinder.html b/xref/org/slf4j/impl/StaticLoggerBinder.html index 6dd51ce80..6d1ac7d75 100644 --- a/xref/org/slf4j/impl/StaticLoggerBinder.html +++ b/xref/org/slf4j/impl/StaticLoggerBinder.html @@ -31,92 +31,94 @@ 23 import org.slf4j.spi.LoggerFactoryBinder; 24 25 /** -26 * The binding of org.slf4j.LoggerFactory class with an actual instance of org.slf4j.ILoggerFactory is performed using information -27 * returned by this class. -28 * -29 * @author colezlaw -30 */ -31 //CSOFF: FinalClass -32 public class StaticLoggerBinder implements LoggerFactoryBinder { -33 //CSON: FinalClass -34 -35 /** -36 * The unique instance of this class -37 */ -38 private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); -39 -40 /** -41 * Return the singleton of this class. -42 * -43 * @return the StaticLoggerBinder singleton -44 */ -45 public static final StaticLoggerBinder getSingleton() { -46 return SINGLETON; -47 } -48 -49 /** -50 * Maven mojos have their own logger, so we'll use one of those -51 */ -52 private Log log = null; -53 -54 /** -55 * Set the Task which will this is to log through. -56 * -57 * @param log the task through which to log -58 */ -59 public void setLog(Log log) { -60 this.log = log; -61 loggerFactory = new MavenLoggerFactory(log); -62 } -63 -64 /** -65 * Declare the version of the SLF4J API this implementation is compiled against. The value of this filed is usually modified -66 * with each release. -67 */ -68 // to avoid constant folding by the compiler, this field must *not* be final -69 //CSOFF: StaticVariableName -70 //CSOFF: VisibilityModifier -71 public static String REQUESTED_API_VERSION = "1.7.12"; // final -72 //CSON: VisibilityModifier -73 //CSON: StaticVariableName -74 -75 /** -76 * The logger factory class string. -77 */ -78 private static final String LOGGER_FACTORY_CLASS = MavenLoggerFactory.class.getName(); -79 -80 /** -81 * The ILoggerFactory instance returned by the {@link #getLoggerFactory} method should always be the same object -82 */ -83 private ILoggerFactory loggerFactory; -84 -85 /** -86 * Constructs the static logger factory. -87 */ -88 private StaticLoggerBinder() { -89 loggerFactory = new MavenLoggerFactory(log); -90 } -91 -92 /** -93 * Returns the logger factory. -94 * -95 * @return the logger factory -96 */ -97 @Override -98 public ILoggerFactory getLoggerFactory() { -99 return loggerFactory; -100 } -101 -102 /** -103 * Returns the logger factory class string. -104 * -105 * @return the logger factory class string -106 */ -107 @Override -108 public String getLoggerFactoryClassStr() { -109 return LOGGER_FACTORY_CLASS; -110 } -111 } +26 * The binding of org.slf4j.LoggerFactory class with an actual instance of +27 * org.slf4j.ILoggerFactory is performed using information returned by this +28 * class. +29 * +30 * @author colezlaw +31 */ +32 //CSOFF: FinalClass +33 public class StaticLoggerBinder implements LoggerFactoryBinder { +34 //CSON: FinalClass +35 +36 /** +37 * The unique instance of this class +38 */ +39 private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); +40 +41 /** +42 * Return the singleton of this class. +43 * +44 * @return the StaticLoggerBinder singleton +45 */ +46 public static final StaticLoggerBinder getSingleton() { +47 return SINGLETON; +48 } +49 +50 /** +51 * Maven mojos have their own logger, so we'll use one of those. +52 */ +53 private Log log = null; +54 +55 /** +56 * Set the Task which will this is to log through. +57 * +58 * @param log the task through which to log +59 */ +60 public void setLog(Log log) { +61 this.log = log; +62 loggerFactory = new MavenLoggerFactory(log); +63 } +64 +65 /** +66 * Declare the version of the SLF4J API this implementation is compiled +67 * against. The value of this filed is usually modified with each release. +68 */ +69 // to avoid constant folding by the compiler, this field must *not* be final +70 //CSOFF: StaticVariableName +71 //CSOFF: VisibilityModifier +72 public static String REQUESTED_API_VERSION = "1.7.12"; // final +73 //CSON: VisibilityModifier +74 //CSON: StaticVariableName +75 +76 /** +77 * The logger factory class string. +78 */ +79 private static final String LOGGER_FACTORY_CLASS = MavenLoggerFactory.class.getName(); +80 +81 /** +82 * The ILoggerFactory instance returned by the {@link #getLoggerFactory} +83 * method should always be the same object +84 */ +85 private ILoggerFactory loggerFactory; +86 +87 /** +88 * Constructs the static logger factory. +89 */ +90 private StaticLoggerBinder() { +91 loggerFactory = new MavenLoggerFactory(log); +92 } +93 +94 /** +95 * Returns the logger factory. +96 * +97 * @return the logger factory +98 */ +99 @Override +100 public ILoggerFactory getLoggerFactory() { +101 return loggerFactory; +102 } +103 +104 /** +105 * Returns the logger factory class string. +106 * +107 * @return the logger factory class string +108 */ +109 @Override +110 public String getLoggerFactoryClassStr() { +111 return LOGGER_FACTORY_CLASS; +112 } +113 }
      diff --git a/xref/org/slf4j/impl/package-frame.html b/xref/org/slf4j/impl/package-frame.html index ddd65e884..bc4c08e1f 100644 --- a/xref/org/slf4j/impl/package-frame.html +++ b/xref/org/slf4j/impl/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.slf4j.impl + Dependency-Check 1.4.0 Reference Package org.slf4j.impl diff --git a/xref/org/slf4j/impl/package-summary.html b/xref/org/slf4j/impl/package-summary.html index c5011a184..bd259e1c0 100644 --- a/xref/org/slf4j/impl/package-summary.html +++ b/xref/org/slf4j/impl/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference Package org.slf4j.impl + Dependency-Check 1.4.0 Reference Package org.slf4j.impl diff --git a/xref/overview-frame.html b/xref/overview-frame.html index e2016d3c0..1ca801587 100644 --- a/xref/overview-frame.html +++ b/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference + Dependency-Check 1.4.0 Reference diff --git a/xref/overview-summary.html b/xref/overview-summary.html index b416e308c..b5bac5318 100644 --- a/xref/overview-summary.html +++ b/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.3.6 Reference + Dependency-Check 1.4.0 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check 1.3.6 Reference

      +

      Dependency-Check 1.4.0 Reference